├── README-zh-Hans.md └── README.md /README-zh-Hans.md: -------------------------------------------------------------------------------- 1 | See also: [Platform Building Cheat Sheet][1] 2 | 3 | # API 设计参考手册 4 | 1. 就像是做自己的产品一样,以资源消费者的角度去设计 API; 5 | * 不是为特定的用户界面设计 API; 6 | * 拥抱变化,针对每一个接口尽量满足灵活性和可调性。(参见 5,6 和 7); 7 | * 吃自己的狗粮,即使你必须模拟一些示例界面。 8 | 9 | 1. 使用资源集合的概念; 10 | * 每种资源有两类网址(接口): 11 | * 资源集合(例如,/orders); 12 | * 集合中的单个资源(例如,/orders/{orderId})。 13 | * 使用复数形式 (使用 ‘orders’ 而不是 ‘order’); 14 | * 资源名称和 ID 组合可以作为一个网址的节点(例如,/orders/{orderId}/items/{itemId}); 15 | * 尽可能的让网址越短越好,单个网址最好不超过三个节点。 16 | 17 | 1. 使用名词作为资源名称 (例如,不要在网址中使用动词); 18 | 19 | 1. 使用有意义的资源描述; 20 | * “禁止单纯的使用 ID!” 响应信息中不应该存在单纯的 ID,应使用链接或是引用的对象; 21 | * 设计资源的描述信息,而不是简简单单的做数据库表的映射; 22 | * 合并描述信息,不要通过两个 ID 直接表示两个表的关系; 23 | 24 | 1. 资源的集合应支持过滤,排序和分页; 25 | 26 | 1. 支持通过链接扩展关系,允许客户端通过添加链接扩展响应中的数据; 27 | 28 | 1. 支持资源的字段裁剪,运行客户端减少响应中返回的字段数量; 29 | 30 | 1. 使用 HTTP 方法名来表示对应的行为: 31 | * POST - 创建资源,非幂等性操作; 32 | * PUT - 更新资源; 33 | * GET - 获取单个资源或资源集合; 34 | * DELETE - 删除单个资源或资源集合; 35 | 36 | 1. 合理使用 HTTP 状态码; 37 | * 200 - 成功; 38 | * 201 - 创建成功,成功创建一个新资源时返回。 返回信息中将包含一个 'Location' 报头,他通过一个链接指向新创建的资源地址; 39 | * 400 - 错误的请求,数据问题,如不正确的 JSON 等; 40 | * 404 - 未找到,通过 GET 请求未找到对应的资源; 41 | * 409 - 冲突,将出现重复的数据或是无效的数据状态。 42 | 43 | 1. 使用 ISO 8601 时间戳格式来表示日期; 44 | 45 | 1. 利用链接策略来处理关联关系,一些流行的例子如下: 46 | * [HAL][2] 47 | * [Siren][3] 48 | * [JSON-LD][4] 49 | * [Collection+JSON][5] 50 | 51 | 1. 使用 [OAuth2][6] 来确保 API 的安全性; 52 | * 使用 Bearer Token 进行身份验证; 53 | * OAuth2 的 Bearer token 要求必须通过 HTTPS / TLS / SSL 来访问你的 API。通过 HTTP 进行的未加密通信将导致窃听和重放。 54 | 55 | 1. Use Content-Type negotiation to describe incoming request payloads. 56 | 57 | 1. Evolution over versioning. However, if versioning, use the Accept header instead of versioning in the URL. 58 | 59 | 1. Consider Cache-ability. At a minimum, use the following response headers: 60 | 61 | 1. 确保你的 GET,PUT,DELETE 请求是[幂等的][7],这些请求多次操作不应该有副作用。 62 | 63 | [1]: https://github.com/RestCheatSheet/platform-cheat-sheet#platform-building-cheat-sheet 64 | [2]: http://stateless.co/hal_specification.html 65 | [3]: https://github.com/kevinswiber/siren 66 | [4]: http://json-ld.org/ 67 | [5]: http://amundsen.com/media-types/collection/ 68 | [6]: http://oauth.net/2/ 69 | [7]: http://www.restapitutorial.com/lessons/idempotency.html -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | See also: [Platform Building Cheat Sheet](https://github.com/RestCheatSheet/platform-cheat-sheet#platform-building-cheat-sheet) 2 | 3 | # API Design Cheat Sheet 4 | 1. Build the API with consumers in mind--as a product in its own right. 5 | * Not for a specific UI. 6 | * Embrace flexibility / tunability of each endpoint (see #5, 6 & 7). 7 | * Eat your own dogfood, even if you have to mockup an example UI. 8 | 9 | 1. Use the Collection Metaphor. 10 | * Two URLs (endpoints) per resource: 11 | * The resource collection (e.g. /orders) 12 | * Individual resource within the collection (e.g. /orders/{orderId}). 13 | * Use plural forms (‘orders’ instead of ‘order’). 14 | * Alternate resource names with IDs as URL nodes (e.g. /orders/{orderId}/items/{itemId}) 15 | * Keep URLs as short as possible. Preferably, no more-than three nodes per URL. 16 | 17 | 1. Use nouns as resource names (e.g. don’t use verbs in URLs). 18 | 19 | 1. Make resource representations meaningful. 20 | * “No Naked IDs!” No plain IDs embedded in responses. Use links and reference objects. 21 | * Design resource representations. Don’t simply represent database tables. 22 | * Merge representations. Don’t expose relationship tables as two IDs. 23 | 24 | 1. Support filtering, sorting, and pagination on collections. 25 | 26 | 1. Support link expansion of relationships. Allow clients to expand the data contained in the response by including additional representations instead of, or in addition to, links. 27 | 28 | 1. Support field projections on resources. Allow clients to reduce the number of fields that come back in the response. 29 | 30 | 1. Use the HTTP method names to mean something: 31 | * POST - create and other non-idempotent operations. 32 | * PUT - update. 33 | * GET - read a resource or collection. 34 | * DELETE - remove a resource or collection. 35 | 36 | 1. Use HTTP status codes to be meaningful. 37 | * 200 - Success. 38 | * 201 - Created. Returned on successful creation of a new resource. Include a 'Location' header with a link to the newly-created resource. 39 | * 400 - Bad request. Data issues such as invalid JSON, etc. 40 | * 404 - Not found. Resource not found on GET. 41 | * 409 - Conflict. Duplicate data or invalid data state would occur. 42 | 43 | 1. Use ISO 8601 timepoint formats for dates in representations. 44 | 45 | 1. Consider connectedness by utilizing a linking strategy. Some popular examples are: 46 | * [HAL](http://stateless.co/hal_specification.html) 47 | * [Siren](https://github.com/kevinswiber/siren) 48 | * [JSON-LD](http://json-ld.org/) 49 | * [Collection+JSON](http://amundsen.com/media-types/collection/) 50 | 51 | 1. Use [OAuth2](http://oauth.net/2/) to secure your API. 52 | * Use a Bearer token for authentication. 53 | * Require HTTPS / TLS / SSL to access your APIs. OAuth2 Bearer tokens demand it. Unencrypted communication over HTTP allows for simple eavesdroppping and impersonation. 54 | 55 | 1. Use Content-Type negotiation to describe incoming request payloads. 56 | 57 | For example, let's say you're doing ratings, including a thumbs-up/thumbs-down and five-star rating. You have one route to create a rating: **POST /ratings** 58 | 59 | How do you distinguish the incoming data to the service so it can determine which rating type it is: thumbs-up or five star? 60 | 61 | The temptation is to create one route for each rating type: **POST /ratings/five_star** and **POST /ratings/thumbs_up** 62 | 63 | However, by using Content-Type negotiation we can use our same **POST /ratings** route for both types. By setting the *Content-Type* header on the request to something like **Content-Type: application/vnd.company.rating.thumbsup** or **Content-Type: application/vnd.company.rating.fivestar** the server can determine how to process the incoming rating data. 64 | 65 | 1. Evolution over versioning. However, if versioning, use the Accept header instead of versioning in the URL. 66 | * Versioning via the URL signifies a 'platform' version and the entire platform must be versioned at the same time to enable the linking strategy. 67 | * Versioning via the Accept header is versioning the resource. 68 | * Additions to a JSON response do not require versioning. However, additions to a JSON request body that are 'required' are troublesome--and may require versioning. 69 | * Hypermedia linking and versioning is troublesome no matter what--minimize it. 70 | * Note that a version in the URL, while discouraged, can be used as a 'platform' version. It should appear as the first node in the path and not version individual endpoints differently (e.g. api.example.com/v1/...). 71 | 72 | 1. Consider Cache-ability. At a minimum, use the following response headers: 73 | * ETag - An arbitrary string for the version of a representation. Make sure to include the media type in the hash value, because that makes a different representation. (ex: ETag: "686897696a7c876b7e") 74 | * Date - Date and time the response was returned (in RFC1123 format). (ex: Date: Sun, 06 Nov 1994 08:49:37 GMT) 75 | * Cache-Control - The maximum number of seconds (max age) a response can be cached. However, if caching is not supported for the response, then no-cache is the value. (ex: Cache-Control: 360 or Cache-Control: no-cache) 76 | * Expires - If max age is given, contains the timestamp (in RFC1123 format) for when the response expires, which is the value of Date (e.g. now) plus max age. If caching is not supported for the response, this header is not present. (ex: Expires: Sun, 06 Nov 1994 08:49:37 GMT) 77 | * Pragma - When Cache-Control is 'no-cache' this header is also set to 'no-cache'. Otherwise, it is not present. (ex: Pragma: no-cache) 78 | * Last-Modified - The timestamp that the resource itself was modified last (in RFC1123 format). (ex: Last-Modified: Sun, 06 Nov 1994 08:49:37 GMT) 79 | 80 | 1. Ensure that your GET, PUT, and DELETE operations are all [idempotent](http://www.restapitutorial.com/lessons/idempotency.html). There should be no adverse side affects from operations. 81 | --------------------------------------------------------------------------------