Skip to content

Commit 493df84

Browse files
committed
feat(): 很多零碎的改动
* 分页: X-Resource-Count -> X-Total-Count * 分页: 把 cursor 找了回来,不过现在叫做 last_cursor 了 * 更细节的接口设计指南: 增加了一些链接
1 parent 745e2dc commit 493df84

File tree

1 file changed

+30
-19
lines changed

1 file changed

+30
-19
lines changed

README.md

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
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
300302
HTTP/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"
364371
HTTP/1.1 302 Found
365372
Access-Control-Allow-Origin: *
366-
Access-Control-Expose-Headers: ETag, Link, X-Resource-Count
373+
Access-Control-Expose-Headers: ETag, Link, X-Total-Count
367374
Access-Control-Allow-Credentials: true
368375
```
369376

@@ -375,7 +382,7 @@ HTTP/1.1 302 Found
375382
Access-Control-Allow-Origin: *
376383
Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With
377384
Access-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
379386
Access-Control-Max-Age: 86400
380387
Access-Control-Allow-Credentials: true
381388
```
@@ -392,7 +399,7 @@ $ curl http://api.example.com/#{RESOURCE_URI}?callback=foo
392399
foo({
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

Comments
 (0)