为了保证持续和及时的更新,强烈推荐在个人Github上关注该项目,欢迎各位star/fork或者帮助翻译html
这篇指南介绍描述了 HTTP+JSON API 的一种设计模式,最初摘录整理自 Heroku 平台的 API 设计指引 Heroku 平台 API 指引。git
这篇指南除了详细介绍现有的 API 外,Heroku 未来新加入的内部 API 也会符合这种设计模式,咱们但愿非 Heroku 员工的API设计者也能感兴趣。github
咱们的目标是保持一致性,专一业务逻辑同时避免过分设计。咱们一直试图找出一种良好的、一致的、显而易见的 API 设计方法,而并非所谓的"最终/理想模式"。json
咱们假设你熟悉基本的 HTTP+JSON API 设计方法,因此本篇指南并不包含全部的 API 设计基础。设计模式
咱们欢迎你为这篇指南作贡献。api
为每一次的响应返回合适的HTTP状态码。 好的响应应该使用以下的状态码:服务器
200
: GET
请求成功,及DELETE
或PATCH
同步请求完成,或者PUT
同步更新一个已存在的资源app
201
: POST
同步请求完成,或者PUT
同步建立一个新的资源dom
202
: POST
,PUT
,DELETE
,或PATCH
请求接收,将被异步处理curl
206
: GET
请求成功,可是只返回一部分,参考:上文中范围分页
使用身份认证(authentication)和受权(authorization)错误码时须要注意:
401 Unauthorized
: 用户未认证,请求失败
403 Forbidden
: 用户无权限访问该资源,请求失败
当用户请求错误时,提供合适的状态码能够提供额外的信息:
422 Unprocessable Entity
: 请求被服务器正确解析,可是包含无效字段
429 Too Many Requests
: 由于访问频繁,你已经被限制访问,稍后重试
500 Internal Server Error
: 服务器错误,确认状态并报告问题
对于用户错误和服务器错误状况状态码,参考: HTTP response code spec
提供所有可显现的资源 (例如: 这个对象的全部属性) ,当响应码为200或是201时返回全部可用资源,包含 PUT
/PATCH
和 DELETE
请求,例如:
$ curl -X DELETE \ https://service.com/apps/1f9b/domains/0fd4 HTTP/1.1 200 OK Content-Type: application/json;charset=utf-8 ... { "created_at": "2012-01-01T12:00:00Z", "hostname": "subdomain.example.com", "id": "01234567-89ab-cdef-0123-456789abcdef", "updated_at": "2012-01-01T12:00:00Z" }
当请求状态码为202时,不返回全部可用资源,例如:
$ curl -X DELETE \ https://service.com/apps/1f9b/dynos/05bd HTTP/1.1 202 Accepted Content-Type: application/json;charset=utf-8 ... {}
在 PUT
/PATCH
/POST
请求的正文(request bodies)中使用JSON格式数据,而不是使用 form 表单形式的数据。这与咱们使用JSON格式返回请求相对应,例如:
$ curl -X POST https://service.com/apps \ -H "Content-Type: application/json" \ -d '{"name": "demoapp"}' { "id": "01234567-89ab-cdef-0123-456789abcdef", "name": "demoapp", "owner": { "email": "username@example.com", "id": "01234567-89ab-cdef-0123-456789abcdef" }, ... }
使用复数形式为资源命名,除非这个资源在系统中是单例的 (例如,在大多数系统中,给定的用户账户只有一个)。 这种方式保持了特定资源的统一性。
好的末尾不须要为资源指定特殊的行为,但在特殊状况下,为某些资源指定行为倒是必要的。为了描述清楚,在行为前加上一个标准的actions
:
/resources/:resource/actions/:action
例如:
/runs/{run_id}/actions/stop
为了和域名命名规则保持一致,使用小写字母并用-
分割路径名字,例如:
service-api.com/users service-api.com/app-setups
属性也使用小写字母,可是属性名要用下划线_
分割,以便在Javascript中省略引号。 例如:
service_class: "first"
在某些状况下,让用户提供ID去定位资源是不方便的。例如,一个用户想取得他在Heroku平台app信息,可是这个app的惟一标识是UUID。这种状况下,你应该支持接口经过名字和ID都能访问,例如:
$ curl https://service.com/apps/{app_id_or_name} $ curl https://service.com/apps/97addcf0-c182 $ curl https://service.com/apps/www-prod
不要只接受使用名字而放弃了使用id。
在一些有父路径/子路径嵌套关系的资源数据模块中,路径可能有很是深的嵌套关系,例如:
/orgs/{org_id}/apps/{app_id}/dynos/{dyno_id}
推荐在根(root)路径下指定资源来限制路径的嵌套深度。使用嵌套指定范围的资源。在上述例子中,dyno属于app,app属于org能够表示为:
/orgs/{org_id} /orgs/{org_id}/apps /apps/{app_id} /apps/{app_id}/dynos /dynos/{dyno_id}