11# API 接口设计指北
22
3- ** 这篇文章受了很多 [ Github 接口文档] ( http://developer.github.com/v3/ ) 以及文中所有提及的协议、标准和文章的启发,因此在顶部注明并加以感谢。**
3+ * 文章主要目的是为设计接口骨架时提供建议
4+ * 内容会经常更新
5+ * ** 只是建议**
46
57## 目录
68
@@ -137,7 +139,7 @@ PS 考虑到存在[夏时制](https://en.wikipedia.org/wiki/Daylight_saving_time
137139
138140### 重定向
139141
140- ** 重定向的新地址都需要在响应的 ` Location ` 头标中返回 **
142+ ** 重定向的新地址都需要在响应头 ` Location ` 中返回 **
141143
142144* 301 ** Moved Permanently** : 被请求的资源已永久移动到新位置
143145* 302 ** Found** : 请求的资源现在临时从不同的 URI 响应请求
@@ -286,29 +288,34 @@ REST 服务的要求之一,客户端不再需要将某些接口的 URI 硬编
286288
287289## 分页
288290
289- 请求某个资源集合时,可以通过指定 `count` 参数来指定每页的资源数量,通过 `page` 参数指定页码。
291+ 请求某个资源集合时,可以通过指定 `count` 参数来指定每页的资源数量,通过 `page` 参数指定页码,或根据 `last_cursor` 参数指定上一页最后一个资源的标识符 。
290292
291293如果没有传递 `count` 参数或者 `count` 参数的值为空,则使用默认值 20 , `count` 参数的最大上限为 100 。
292294
293- 分页的相关信息会包含在 [Link Header](http://tools.ietf.org/html/rfc5988) 和 `X-Resource-Count` 中 。
295+ 如何同时传递了 `last_cursor` 和 `page` 参数,则使用 `page` 。
294296
295- 如果是第一页或者是最后一页时,不会返回 `prev` 和 `next` 的 Link 。
297+ 分页的相关信息会包含在 [Link Header](http://tools.ietf.org/html/rfc5988) 和 `X-Total-Count` 中 。
296298
297- 更多 `rel` 相关信息,可以参阅 [RFC5988 6.2.2节](http://tools.ietf.org/html/rfc5988#section-6.2.2) 。
299+ 如果是第一页或者是最后一页时,不会返回 `previous` 和 `next` 的 Link 。
298300
299301```http
300302HTTP/1.1 200 OK
301- X-Resource -Count: 542
302- Link: <http://api.example.com/#{RESOURCE_URI}?cursor =&count=100>; rel="first",
303- <http://api.example.com/#{RESOURCE_URI}?cursor=90 &count=100>; rel="prev",
304- <http://api.example.com/#{RESOURCE_URI}?cursor=120 &count=100>; rel="next ",
305- <http://api.example.com/#{RESOURCE_URI}?cursor=200 &count=100>; rel="last"
303+ X-Total -Count: 542
304+ Link: <http://api.example.com/#{RESOURCE_URI}?last_cursor =&count=100>; rel="first",
305+ <http://api.example.com/#{RESOURCE_URI}?last_cursor=200 &count=100>; rel="last"
306+ <http://api.example.com/#{RESOURCE_URI}?last_cursor=90 &count=100>; rel="previous ",
307+ <http://api.example.com/#{RESOURCE_URI}?last_cursor=120 &count=100>; rel="next",
306308
307309[
308310 ...
309311]
310312```
311313
314+ 相关资料:
315+
316+ * [ RFC5005 第3节 《Paged Feeds》] ( http://tools.ietf.org/html/rfc5005#section-3 )
317+ * [ RFC5988 6.2.2节 《Initial Registry Contents》] ( http://tools.ietf.org/html/rfc5988#section-6.2.2 )
318+
312319## 数据缓存
313320
314321大部分接口应该在响应头中携带 ` Last-Modified ` 和 ` ETag ` 信息,客户端可以在随后请求这些资源的时候,在请求头中使用 ` If-Modified-Since ` 或者 ` If-None-Match ` 两个头来确认资源是否经过修改。
@@ -363,7 +370,7 @@ HTTP/1.1 302 Found
363370$ curl -i https://api.example.com -H " Origin: http://example.com"
364371HTTP/1.1 302 Found
365372Access-Control-Allow-Origin: *
366- Access-Control-Expose-Headers: ETag, Link, X-Resource -Count
373+ Access-Control-Expose-Headers: ETag, Link, X-Total -Count
367374Access-Control-Allow-Credentials: true
368375```
369376
@@ -375,7 +382,7 @@ HTTP/1.1 302 Found
375382Access-Control-Allow-Origin: *
376383Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With
377384Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE
378- Access-Control-Expose-Headers: ETag, Link, X-Resource -Count
385+ Access-Control-Expose-Headers: ETag, Link, X-Total -Count
379386Access-Control-Max-Age: 86400
380387Access-Control-Allow-Credentials: true
381388```
@@ -392,7 +399,7 @@ $ curl http://api.example.com/#{RESOURCE_URI}?callback=foo
392399foo ({
393400 " meta" : {
394401 " status" : 200 ,
395- " X-Resource -Count" : 542 ,
402+ " X-Total -Count" : 542 ,
396403 " Link" : [
397404 {" href" : " http://api.example.com/#{RESOURCE_URI}?cursor=0&count=100" , " rel" : " first" },
398405 {" href" : " http://api.example.com/#{RESOURCE_URI}?cursor=90&count=100" , " rel" : " prev" },
@@ -406,12 +413,16 @@ foo({
406413
407414## 更细节的接口设计指南
408415
409- 推荐参考文档 [ HTTP API Design Guide ] ( https://github.com/interagent/http-api-design/ ) 来设计 REST 风格的 API ,我基本同意这个文档上的所有建议,除了以下两点 :
416+ 这里还有一些其他参考资料 :
410417
411- * [ Use consistent path formats] ( https://github.com/interagent/http-api-design/#use-consistent-path-formats )
412- 还是不建议将动作写在 URL 中,像文档中的情况,可以将这个行为抽象成一个事务资源 ` POST /runs/:run_id/stop-logs ` 或者 ` POST /runs/:run_id/stoppers ` 来解决
413- * [ Paginate with Ranges] ( https://github.com/interagent/http-api-design/#paginate-with-ranges )
414- 确实是一个巧妙的设计,但似乎并不符合 ` Content-Range ` 的设计意图,而且有可能和需要使用到 ` Content-Range ` 的正常场景冲突(虽然几乎不可能),所以不推荐
418+ * 推荐参考文档 [ HTTP API Design Guide] ( https://github.com/interagent/http-api-design/ ) 来设计 REST 风格的 API ,我基本同意这个文档上的所有建议,除了以下两点:
419+ * [ Use consistent path formats] ( https://github.com/interagent/http-api-design/#use-consistent-path-formats )
420+ 还是不建议将动作写在 URL 中,像文档中的情况,可以将这个行为抽象成一个事务资源 ` POST /runs/:run_id/stop-logs ` 或者 ` POST /runs/:run_id/stoppers ` 来解决
421+ * [ Paginate with Ranges] ( https://github.com/interagent/http-api-design/#paginate-with-ranges )
422+ 确实是一个巧妙的设计,但似乎并不符合 ` Content-Range ` 的设计意图,而且有可能和需要使用到 ` Content-Range ` 的正常场景冲突(虽然几乎不可能),所以不推荐
423+ * [ Best Practices for Designing a Pragmatic RESTful API] ( http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api )
424+ * [ Thoughts on RESTful API Design] ( http://restful-api-design.readthedocs.org/en/latest/ )
425+ * [ The RESTful CookBook] ( http://restcookbook.com/ )
415426
416427[ iso3166-1 ] : javascript:;
417428[ iso3166-1_wiki ] : http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
0 commit comments