RESTful最佳实践
-
使用名词而不是动词;
-
GET方法和查询参数不能改变资源状态;
-
使用名词复数,不要混淆名词单复数。保持简单,只用复数名词来定义所有资源;
- /car => /cars
- /user => /users
-
使用子资源来表达资源间的关系;
- GET /cars/711/drivers => 返回711号car的所有drivers列表
- GET /cars/711/drivers/4 => 返回711号car的4号driver
-
使用HTTP header来序列化格式;
- Content-Type: application/json
- Accept: text/html
-
使用HATEOAS约束;
- 第一个层次的Web服务使用HTTP作为传输方式,实际上只是远程方法调用的一种具体形式。SOAP和XML-RPC都属于此类;
- 第二个层次的Web服务引入了资源的概念,每个资源有对应的标志符;
- 第三个层次的Web服务使用HTTP方法进行不同的操作,并且使用不同的HTTP状态码表示不同的结果;
- 第四个层次的Web服务使用HATEOAS。在资源表达式中包含链接信息,客户端根据链接发现可以执行的动作;
{ "id": 711, "manufacturer": "bmw", "model": "X5", "seats": 5, "drivers": [ { "id": 23, "name": "Stefan Jauker", "links": [ { "rel": "self", "href": "/api/v1/drivers/23" } ] } ] }
-
提供过滤、排序、字段选择、分页;
- GET /cars?color=red
- GET /cars?sort=-manufactorer,+model
- GET /cars?fields=manufacturer,model,id,color
- GET /cars?offset=10&limit=5
-
API版本化;
- /blog/api/v1
-
充分使用HTTP状态码来处理错误;
HTTP状态码是用来表示网页服务器HTTP响应状态的3位数字代码。在设计API处理错误时,应该充分使用HTTP状态码,而不是简单地抛出一个“500 - Internal Server Error”。所有的异常都应该有一个错误的payload作为映射,下面是一个例子:
{ "errors": [ { "userMessage": "...", "internalMessage": "...", "code": 34, "moreInfo": "..." } ] }
需要注意的是部分“老年人”对RESTful的理解就是只使用HTTP状态码,多余信息不再返回,这显然是不合理的。