RESTful API基础知识

协议

API与用户的通信协议采用https协议。

域名

域名尽量部署在专属域名之下。 考虑到API的扩展性,放在二级域名下: https://api.example.com 如果确定不会有进一步扩展,可以考虑放在主域名之下: https://example.com/api/

版本

应将API的版本号放入URL中 https://api.example.com/v1/

路径

路径又称终点(endpoint),表示API的具体网址。 在RESTful架构中,每一个网站代表一个资源,所以网址中不能有动词,只能有名词,且一般所用的名词与数据库的表名对应。

HTTP动词

对于资源的具体操作,由HTTP动词表示。 常用的HTTP动词有以下五个(括号中代表的是对应的sql)

GET(select):从服务器中取出资源。
POST(create):在服务器中新建一个资源。
PUT(update):在服务更新全体资源。(是幂等)
PATCH(update):在服务器更新局部资源。(不是幂等)
DELETE(delete):从服务器删除资源。

过滤信息

如果记录过多,则需要api提供过滤参数,服务器根据过滤参数返回过滤结果。 常见过滤参数:

limit: 指定返回的数量
offset:指定偏移量
page:第几页
per_page:每页的记录数
sortby:指定返回结果按照哪个属性排序
order:排序顺序

状态码

服务器向用户返回的状态码和提示信息,常见如下:

200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。
201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
204 NO CONTENT - [DELETE]:用户删除数据成功。
400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。
401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。
404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。
406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。
410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。
422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。
500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。

错误处理

如果状态码是4xx,就应该向用户返回出错信息,通常来说都是将error作为键名,错误信息作为键值返回,例如:

{
  "error":"error detail"
}

返回结果

'RESTful API'最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。 比如,当用户向api.example.com的根目录发出请求,会得到这样一个文档。

{"link": {
  "rel":   "collection https://www.example.com/zoos",
  "href":  "https://api.example.com/zoos",
  "title": "List of zoos",
  "type":  "application/vnd.yourformat+json"
}}

上面代码表示,文档中有一个link属性,用户读取这个属性就知道下一步该调用什么API了。rel表示这个API与当前网址的关系(collection关系,并给出该collection的网址),href表示API的路径,title表示API的标题,type表示返回类型。

其他

  • API的身份认证应该使用OAuth 2.0框架。
  • 服务器返回的数据格式,应该尽量使用JSON,避免使用xml。

拓展阅读

  • https://opensource.zalando.com/restful-api-guidelines/#introduction
  • https://docs-apis.apigee.io/files/Web-design-the-missing-link-ebook-2016-11.pdf
  • http://jsonapi.org.cn/format/
  • https://jsonapi.org/format/1.1/