方法 | 操做 | 场景html |
GET | 读 | /cars /cars/711 |
POST | 建立 | /cars |
PUT | 修改 | /cars/711 /cars |
PATCH | 部分修改 | /cars/711 |
DELETE | 删除 | /cars/711 |
GET /tickets - 获取 tickets 列表
GET /tickets/12 - 获取一个单独的 ticket
POST /tickets - 建立一个新的 ticket
PUT /tickets/12 - 更新 ticket #12
PATCH /tickets/12 - 部分更新 ticket #12
DELETE /tickets/12 - 删除 ticket #12api
不要使用GET 进行状态改变,浏览器
GET /users/711?activate
GET /users/711/activate
若是一个资源与另一个资源有关系,使用子资源:缓存
GET /tickets/12/messages - 获取ticket #12下的消息列表 GET /tickets/12/messages/5 - 获取ticket #12下的编号为5的消息 POST /tickets/12/messages - 为ticket #12建立一个新消息 PUT /tickets/12/messages/5 - 更新ticket #12下的编号为5的消息 PATCH /tickets/12/messages/5 - 部分更新ticket #12下的编号为5的消息 DELETE /tickets/12/messages/5 - 删除ticket #12下的编号为5的消息
在客户端和服务端,双方都要知道通信的格式,格式在HTTP-Header中指定服务器
Content-Type 定义请求格式
Accept 定义系列可接受的响应格式restful
最好是尽可能保持基本资源URL的简洁性。 复杂结果过滤器、排序需求和高级搜索 (当限定在单一类型的资源时) ,都可以做为在基本URL之上的查询参数来轻松实现。下面让咱们更详细的看一下:网络
1)过滤: 对每个字段使用一个惟一查询参数,就能够实现过滤。 例如,当经过“/tickets”终端来请求一个票据列表时,你可能想要限定只要那些在售的票。这能够经过一个像app
GET /tickets?state=open
这样的请求来实现。这里“state”是一个实现了过滤功能的查询参数。负载均衡
2)排序: 跟过滤相似, 一个泛型参数排序能够被用来描述排序的规则. 为适应复杂排序需求,让排序参数采起逗号分隔的字段列表的形式,每个字段前均可能有一个负号来表示按降序排序。咱们看几个例子:搜索引擎
GET /tickets?sort=-priority - 获取票据列表,按优先级字段降序排序 GET /tickets?sort=-priority,created_at - 获取票据列表,按“priority”字段降序排序。在一个特定的优先级内,较早的票排在前面
3)搜索: 有时基本的过滤不能知足需求,这时你就须要全文检索的力量。或许你已经在使用 ElasticSearch 或者其它基于 Lucene 的搜索技术。当全文检索被用做获取某种特定资源的资源实例的机制时, 它能够被暴露在API中,做为资源终端的查询参数,咱们叫它“q”。搜索类查询应当被直接交给搜索引擎,而且API的产出物应当具备一样的格式,以一个普通列表做为结果。
把这些组合在一块儿,咱们能够建立如下一些查询:
GET /tickets?sort=-updated_at - 获取最近更新的票 GET /tickets?state=closed&sort=-updated_at - 获取最近更新而且状态为关闭的票。 GET /tickets?q=return&state=open&sort=-priority,created_at - 获取优先级最高、最早建立的、状态为开放的票,而且票上有 'return' 字样。
4)通常查询定义方式
为了使普通用户的API使用体验更加愉快, 考虑把条件集合包装进容易访问的RESTful 路径中。好比上面的,最近关闭的票的查询能够被包装成
GET /tickets/recently_closed
5)限制查询返回字段
API的使用者并不老是须要一个资源的完整表示。选择返回字段的功能由来已久,它使得API使用者可以最小化网络阻塞,并加速他们对API的调用。
使用一个字段查询参数,它包含一个用逗号隔开的字段列表。例如,下列请求得到的信息将刚刚足够展现一个在售票的有序列表:
GET /tickets?fields=id,subject,customer_name,updated_at&state=open&sort=-updated_at
6)Paging分页
使用 limit 和offset.实现分页,缺省limit=20 和offset=0;
GET /cars?offset=10&limit=5
为了将总数发给客户端,使用订制的HTTP头: X-Total-Count.
连接到下一页或上一页能够在HTTP头的link规定,遵循Link规定:
Link: <https://blog.mwaysolutions.com/sample/api/v1/cars?offset=15&limit=5>; rel="next", <https://blog.mwaysolutions.com/sample/api/v1/cars?offset=50&limit=3>; rel="last", <https://blog.mwaysolutions.com/sample/api/v1/cars?offset=0&limit=5>; rel="first", <https://blog.mwaysolutions.com/sample/api/v1/cars?offset=5&limit=5>; rel="prev",
一个 PUT, POST 或者 PATCH 调用可能会对指定资源的某些字段形成更改,而这些字段本不在提供的参数之列 (例如: created_at 或 updated_at 这两个时间戳)。 为了防止API使用者为了获取更新后的资源而再次调用该API,应当使API把更新(或建立)后的资源做为response的一部分来返回。
以一个产生建立活动的 POST 操做为例, 使用一个 HTTP 201 状态代码 而后包含一个 Location header 来指向新生资源的URL。
选定一种方式:snake_case vs camelCase
一个提供空白符压缩输出的API,从浏览器中查看结果并不美观。虽然一些有序的查询参数(如 ?pretty=true )能够提供来使漂亮打印生效,一个默认状况下能进行漂亮打印的API更为平易近人。额外数据传输的成本是微不足道的,尤为是当你比较不执行gzip压缩的成本。
考虑一些用例:假设分析一个API消费者正在调试而且有本身的代码来打印出从API收到的数据——默认状况下这应是可读的。或者,若是消费者抓住他们的代码生成的URL,并直接从浏览器访问它——默认状况下这应是可读的。这些都是小事情。作好小事情会使一个API能被更愉快地使用
就像一个HTML错误页面给访问者展现了有用的错误信息同样,一个API应当以一种已知的可以使用的格式来提供有用的错误信息。 错误的表示形式应当和其它任何资源没有区别,只是有一套本身的字段。
API应当老是返回有意义的HTTP状态代码。API错误一般被分红两种类型: 表明客户端问题的400系列状态码和表明服务器问题的500系列状态码。最简状况下,API应当把便于使用的JSON格式做为400系列错误的标准化表示。若是可能(意思是,若是负载均衡和反向代理能建立自定义的错误实体), 这也适用于500系列错误代码。
一个JSON格式的错误信息体应当为开发者提供几样东西 - 一个有用的错误信息,一个惟一的错误代码 (可以用来在文档中查询详细的错误信息) 和可能的详细描述。这样一个JSON格式的输出可能会像下面这样:
{ "code" : 1234, "message" : "Something bad happened :(", "description" : "More details about the error here" }
对PUT, PATCH和POST请求进行错误验证将须要一个字段分解。下面多是最好的模式:使用一个固定的顶层错误代码来验证错误,并在额外的字段中提供详细错误信息,就像这样:
{ "code" : 1024, "message" : "Validation Failed", "errors" : [ { "code" : 5432, "field" : "first_name", "message" : "First name cannot have fancy characters" }, { "code" : 5622, "field" : "password", "message" : "Password cannot be blank" } ] }
HTTP定义了一套能够从API返回的有意义的状态代码。 这些代码可以用来帮助API使用者对不一样的响应作出相应处理。我已经把你必然会用到的那些列成了一个简短的清单:
----------------------------------------------------------------------
参考资料:
一、《Best Practices for Designing a Pragmatic RESTful API》
二、《RESTful API 设计最佳实践》(对上文的译文)
三、《Principles of good RESTful API Design》