Restful API

简单使用 Restful 风格API

RESTful API 是写给开发者来消费的,其命名和结构需要有意义。因此,在设计和编写URL时,要符合一些规范,本文只列出一些关键点。
  1. 规范的API应该包含版本信息,在RESTful API中,最简单的包含版本的方法是将版本信息放到url中,如:

    /api/v1/posts/
    /api/v1/drafts/ 
    //******
    /api/v2/posts/
    /api/v2/drafts/

    另一种优雅的做法是,使用HTTP header中的accept来传递版本信息,这也是GitHub API 采取的策略

  2. RESTful API 中的url是指向资源的,而不是描述行为的,因此设计API时,应使用名词而非动词来描述语义,否则会引起混淆和语义不清。 Url只能有名词(每个url代表一种资源(resource),所以Url不能有动词,只能有名词) 单数名词表示单个资源,复数名词表示所有资源
    获取单个产品:http://127.0.01:8080/AppName/rest/product/1
    获取多个产品:  http://127.0.01:8080/AppName/rest/products
# Bad APIs
/api/getArticle/1/
/api/updateArticle/1/
/api/deleteArticle/1/

上面四个url都是指向同一个资源的,虽然一个资源允许多个url指向它,但不同的url应该表达不同的语义,上面的API可以优化为:

# Good APIs
/api/Article/1/

article 资源的获取、更新和删除分别通过 GET, PUTDELETE方法请求API即可。

  1. 如果要获取一个资源子集,采用 nested routing 是一个优雅的方式,如,列出所有文章中属于Gevin编写的文章:
    # List Gevin's articles
    /api/authors/gevin/articles/
  2. 获取资源子集的另一种方式是基于filter
    # List Gevin's articles
    /api/articles?author=gevin
  3. 分页就是一种最典型的资源过滤,分页获取是一种比较合理的方式。如果基于开发框架(如Django REST Framework),直接使用开发框架中的分页机制即可,如果是自己实现分页机制,Gevin的策略是: 返回资源集合是,包含与分页有关的数据如下:
    {
    "page": 1,            # 当前是第几页
    "pages": 3,           # 总共多少页
    "per_page": 10,       # 每页多少数据
    "has_next": true,     # 是否有下一页数据
    "has_prev": false,    # 是否有前一页数据
    "total": 27           # 总共多少数据
    }

    当想API请求资源集合时,可选的分页参数为:

    参数  含义
    page    当前是第几页,默认为1
    per_page    每页多少条记录,默认为系统默认值
  4. Url是区分大小写的,这点经常被忽略
    /Posts
    /posts
    //不同的URL
  5. 目前比较流行的API设计方案,通常建议url以/作为结尾,如果API GET请求中,url不以/结尾,则重定向到以/结尾的API上去(这点现在的web框架基本都支持),因为有没有 /,也是两个url,即:
    /posts/
    /posts
    //也是不同的URL
  6. RESTful API 应具备良好的可读性,当url中某一个片段(segment)由多个单词组成时,建议使用 - 来隔断单词,而不是使用 _,即:
    # Good
    /api/featured-post/
    # Bad
    /api/featured_post/