RESTful API 设计

RESTful API 设计

RESTful 是目前最流行的 API 设计规范,用于 Web 数据接口的设计。RESTful 的核心思想就是,客户端发出的数据操作指令都是"动词 + 宾语"的结构。比如,GET /articles这个命令,GET是动词,/articles是宾语。动词在HTTP协议的请求方法体现,宾语则在URL中体现。


一、请求方法

通常就是五种 HTTP 方法对应 CRUD 操作:

  • GET:读取(Read)

  • POST:新建(Create)

  • PUT:更新(Update)

  • PATCH:更新(Update),通常是部分更新

  • DELETE:删除(Delete)

有些客户端只能使用GETPOST这两种方法。服务器必须接受POST模拟其他三个方法(PUTPATCHDELETE)。这时,客户端发出的 HTTP 请求,要加上X-HTTP-Method-Override属性,告诉服务器应该使用哪一个动词,覆盖POST方法。

POST /api/Person/4 HTTP/1.1  
X-HTTP-Method-Override: PUT

二、URL


2.1 使用名词

宾语就是 API 的 URL,是 HTTP 动词作用的对象。它应该是名词不能是动词


2.2 使用名词复数

  • API表示获取一个数据集合时,使用复数表示,如GET /articles(获取所有文章)

  • API表示获取一个数据集合中的单个数据元素时,这个集合也建议使用复数,如GET /articles/2(获取编号为2的文章)


2.3 避免多级 URL

资源需要多级分类时,写出多级的 URL不利于扩展,语义也不明确:

GET /authors/12/categories/2

更好的做法是,除了第一级,其他级别都用查询字符串表达:

GET /authors/12?categories=2
GET /articles?published=true

三、响应状态码

客户端的每一次请求,服务器都必须给出回应。以下四种状态码,覆盖了绝大部分 API响应 可能遇到的情况:

  • 2xx:操作成功

  • 3xx:重定向

  • 4xx:客户端错误

  • 5xx:服务器错误

每一种状态码都有标准的(或者约定的)解释,客户端只需查看状态码,就可以判断出发生了什么情况,所以服务端应返回尽可能精确的状态码


3.1 2xx状态码

  • GET:200 OK

  • POST:201 Created(表示生成了新的资源)

  • PUT:200 OK

  • PATCH:200 OK

  • DELETE:204 No Content(表示资源已经不存在)

  • 202 Accepted(表示服务器已经收到请求,但还未进行处理,会在未来再处理,通常用于异步操作)


3.2 3xx状态码

API 级别用到的的3xx状态码主要是303 See Other,表示参考另一个 URL。

它与302307的含义一样,也是"暂时重定向",区别在于302307用于GET请求,而303用于POSTPUTDELETE请求。收到303以后,浏览器不会自动跳转,而会让用户自己决定下一步怎么办,例如:

HTTP/1.1 303 See Other
Location: /api/orders/12345

3.3 4xx状态码

4xx状态码表示客户端错误,主要有下面几种:

  • 400 Bad Request:服务器不理解客户端的请求,未做任何处理。

  • 401 Unauthorized:用户未提供身份验证凭据,或者没有通过身份验证。

  • 403 Forbidden:用户通过了身份验证,但是不具有访问资源所需的权限。

  • 404 Not Found:所请求的资源不存在,或不可用。

  • 405 Method Not Allowed:用户已经通过身份验证,但是所用的 HTTP 方法不在他的权限之内。

  • 410 Gone:所请求的资源已从这个地址转移,不再可用。

  • 415 Unsupported Media Type:客户端要求的返回格式不支持。如:API 只能返回 JSON 格式,但是客户端要求返回 XML 格式。

  • 422 Unprocessable Entity :客户端上传的附件无法处理,导致请求失败。

  • 429 Too Many Requests:客户端的请求次数超过限额。


3.4 5xx状态码

5xx状态码表示服务端错误。一般来说,API 不会向用户透露服务器的详细信息,所以只要两个状态码就够了。

  • 500 Internal Server Error:客户端请求有效,服务器处理时发生了意外。

  • 503 Service Unavailable:服务器无法处理请求,一般用于网站维护状态。


四、响应体


4.1 返回json对象

  • 请求头中的ACCEPT属性要设成application/json,告诉服务器,可以接受 JSON 格式

  • 响应头中的Content-Type属性要设为application/json


4.2 返回与状态码匹配的内容

状态码应与响应体的内容匹配,如下示例就不匹配:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "status": "failure",
  ...
}

响应内容应该与状态码体现的语义相同或相配合,易于理解,修改后:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "error": "Invalid payoad.",
  ...
}

4.3 提供连接

在设计良好的RESTful API 中,客户端只需知道几个*资源的 URL,其他资源的 URL 则从响应中包含的链接上发掘。这就好比浏览网络时,你在自己知道的网页中点击链接发掘新网页一样。

例如GitHub 的 API 都在 api.github.com 这个域名。访问它,就可以得到其他 URL:

{
  ...
  "feeds_url": "https://api.github.com/feeds",
  "followers_url": "https://api.github.com/user/followers",
  "following_url": "https://api.github.com/user/following{/target}",
  "gists_url": "https://api.github.com/gists{/gist_id}",
  "hub_url": "https://api.github.com/hub",
  ...
}

参考

上一篇:什么是RESTful API


下一篇:使用 Python 写一个友好的 API 还是很重要的