RESTful API规范

2016-09-07 14:03:06来源:oschina作者:ayoway人点击

按照Richardson Maturity Mode对REST评价的模型,规范基于level2来设计。


资源
路径

路径,API的具体地址。在REST中,每个地址都代表一个具体的资源(Resource)。所以就有了以下的约定:

路径仅表示资源的路径(位置),以及一些特殊的actions操作。
以复数(名词)进行命名资源,不管返回单个或者多个资源。
使用小写字母、数字以及下划线(“_”)。(下划线是为了区分多个单词,如token_access)。
资源的路径从父到子依次如:/{resource}/{resource_id}/{sub_resource}/{sub_resource_id}/{sub_resource_property}。
使用?来进行资源的过滤、搜索以及分页等。
使用版本号,且版本号在资源路径之前。
优先使用内容协商来区分表述格式,而不是使用后缀来区分表述格式。
应该放在一个专用的域名下,如:http://api.webfuse.cn。
建议使用SSL。

综上,一个API路径可能会是


https://api.webfuse.cn/v0.1/{resource}/{resource_id}/{sub_resource}/{sub_resource_id}/{sub_resource_property}
https://api.webfuse.cn/v0.1/{resource}?limit=10&offset=10
https://api.webfuse.cn/v0.1/{resource}?page=1&page_size=10
https://api.webfuse.cn/v0.1/{resource}?sortby=name&order=asc操作

用HTTP动词(方法)表示对资源的具体操作。常用的HTTP动词有:


GET:从服务器取出资源(一项或多项)。
POST:在服务器新建一个资源。
PUT:在服务器更新资源(客户端提供改变后的完整资源,全部更新)。
PATCH:在服务器更新资源(客户端提供改变的属性,部分更新)。
DELETE:从服务器删除资源。
HEAD:获取资源的元数据。
OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的。

所以,


GEThttps://api.webfuse.cn/v0.1/users获得用户列表
GEThttps://api.webfuse.cn/v0.1/users/{id}获得指定的用户
POST https://api.webfuse.cn/v0.1/users创建一个用户
PUThttps://api.webfuse.cn/v0.1/users/{id}更新指定的用户(提供该用户的全部信息)
PATCHhttps://api.webfuse.cn/v0.1/users/{id}更新指定的用户(提供该用户的部分信息)
DELETE https://api.webfuse.cn/v0.1/users/{id}删除指定的用户数据

数据是对资源的具体描述,分为请求数据和返回数据。约定如下:

查询,过滤条件使用query string。
Content body 仅仅用来传输数据。
通过Content-Type指定请求与返回的数据格式。其中请求数据还要指定Accept。
数据应该拿来就能用,不应该还要进行转换操作。
使用ISO-8601格式表达时间字段,例如: 2014-04-05T14:30Z。
采用UTF-8编码。
返回的数据应该尽量简单,响应状态应该包含在响应头中。
使用小写字母、数字以及下划线(“_”)描述字段,不使用大写描述字段。
建议资源使用UUID最为唯一标识。同时建议命名为id。
属性和字符串值必须使用双引号””。
建议对每个字段设置默认值(数组型可设置为[],字符串型可设置为””,数值可设置为0,对象可设置为{}),这一条是为了方便前端/客户端进行判断字段存不存在操作。
POST操作应该返回新建的资源;PUT/PATCH操作返回更新后的完整的资源;DELETE返回一个空文档;GET返回资源数组或当个资源;
为了方便以后的扩展兼容,如果返回的是数组,强烈建议用一个包含如items属性的对象进行包裹。如:{"items":[{},{}]}

所以,一个请求以及返回的数据结构可能如:


POST https://api.webfuse.cn/v0.1/users
Request
headers:
Accept: application/json
Content-Type: application/json;charset=UTF-8
body:
{
"user_name": "HingKwan",
"id":"550e8400-e29b-41d4-a716-446655440000"
}
Response
status: 201 Created
headers:
Content-Type: application/json;charset=UTF-8
body:
{
"user_name": "HingKwan",
"id":"550e8400-e29b-41d4-a716-446655440000"
}安全
调用限制

为了避免请求泛滥,给API设置速度限制很重要。入速度设置之后,可以在HTTP返回头上对返回的信息进行说明,下面是几个必须的返回头(依照twitter的命名规则):


X-Rate-Limit-Limit :当前时间段允许的并发请求数
X-Rate-Limit-Remaining:当前时间段保留的请求数。
X-Rate-Limit-Reset:当前时间段剩余秒数授权校验

RESTful API是无状态的也就是说用户请求的鉴权和cookie以及session无关,每一次请求都应该包含鉴权证明。


可以使用http请求头Authorization设置授权码; 必须使用User-Agent设置客户端信息, 无User-Agent请求头的请求应该被拒绝访问。具体的授权可以采用OAuth2,或者自己定义并实现相关的授权验证机制(基于token)。


常见的请求Header为:


User-Agent: Data-Server-Client
Authorzation: Bearer 383w9JKJLJFw4ewpie2wefmjdlJLDJF


User-Agent: Data-Server-Client
Authorzation: MAC,nonce="14187532423423:adfadsfa",mac="SfadfaFdafadfdasFFyu"

以上两个代码只是列出来可以采用的格式,具体的实现可以根据各项目具体规划。


错误

当API返回非2XX的HTTP响应时,应该采用统一的响应信息,格式如:


HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
{
"code":"INVALID_ARGUMENT",
"message":"{error message}",
"request_id":"",
"host_id":"{server identity}",
"server_time":"2016-05-17T22:08:00Z"
"document":"https://developer.webfuse.cn/v0.1/errors/400"
}
HTTP Header Code:符合HTTP响应的状态码。详细见以下的“状态码”节。
code:用来表示某类错误,比如缺少参数等。是对HTTP Header Code的补充,开发团队可以根据自己的需要自己定义。
message:错误信息的摘要,应该是对用户处理错误有用的信息。
request_id:请求的id,方便开发定位发生错误的请求(可选)。
host_id:服务器实例的ID,方便开发定位是哪台服务器实例发生了错误(可选)。
server_time:发生错误时候的服务器时间(可选)。
document:错误解决的文档(方便前端展示,可选)。

code的定义约定:

采用大写字母命名,字母与字母之间用下划线(”_”)隔开。
采用{biz_name}/{err_code}的命名结构。其中biz_name为业务名称的缩写。
code应该用来定义错误类别,而非定义具体的某个错误。 状态码

为每个请求返回适当的状态码,状态码可以参考HTTP的状态码。


常用的状态码有:


200 ok- 成功返回状态,对应,GET,PUT,PATCH,DELETE。
201 created- 成功创建。
304 not modified - HTTP缓存有效。
400 bad request - 请求格式错误。
401 unauthorized - 未授权。
403 forbidden - 鉴权成功,但是该用户没有权限。
404 not found - 请求的资源不存在
405 method not allowed - 该http方法不被允许。
410 gone - 这个url对应的资源现在不可用。
415 unsupported media type - 请求类型错误。
422 unprocessable entity - 校验错误时用。
429 too many request - 请求过多。
500 internal server error - 通用错误响应。
503 service unavailable - 服务当前无法处理请求。

REST (REpresentation State Transfer) 描述了一个架构样式的网络系统,比如 web 应用程序。它首次出现在 2000 年 Roy Fielding 的博士论文中,他是 HTTP 规范的主要编写者之一。REST 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。


Web 应用程序最重要的 REST 原则是,客户端和服务器之间的交互在请求之间是无状态的。从客户端到服务器的每个请求都必须包含理解请求所必需的信息。如果服务器在请求之间的任何时间点重启,客户端不会得到通知。此外,无状态请求可以由任何可用服务器回答,这十分适合云计算之类的环境。客户端可以缓存数据以改进性能。


在服务器端,应用程序状态和功能可以分为各种资源。资源是一个有趣的概念实体,它向客户端公开。资源的例子有:应用程序对象、数据库记录、算法等等。每个资源都使用 URI (Universal Resource Identifier) 得到一个惟一的地址。所有资源都共享统一的界面,以便在客户端和服务器之间传输状态。使用的是标准的 HTTP 方法,比如 GET、PUT、POST 和 DELETE。Hypermedia 是应用程序状态的引擎,资源表示通过超链接互联。


另一个重要的 REST 原则是分层系统,这表示组件无法了解它与之交互的中间层以外的组件。通过将系统知识限制在单个层,可以限制整个系统的复杂性,促进了底层的独立性。


当 REST 架构的约束条件作为一个整体应用时,将生成一个可以扩展到大量客户端的应用程序。它还降低了客户端和服务器之间的交互延迟。统一界面简化了整个系统架构,改进了子系统之间交互的可见性。REST 简化了客户端和服务器的实现。


RESTful Web 服务与 RPC 样式的 Web 服务


了解了什么是什么是REST,我们再看看RESTful的实现。最近,使用 RPC 样式架构构建的基于 SOAP 的 Web 服务成为实现 SOA 最常用的方法。RPC 样式的 Web 服务客户端将一个装满数据的信封(包括方法和参数信息)通过 HTTP 发送到服务器。服务器打开信封并使用传入参数执行指定的方法。方法的结果打包到一个信封并作为响应发回客户端。客户端收到响应并打开信封。每个对象都有自己独特的方法以及仅公开一个 URI 的 RPC 样式 Web 服务,URI 表示单个端点。它忽略 HTTP 的大部分特性且仅支持 POST 方法。


由于轻量级以及通过 HTTP 直接传输数据的特性,Web 服务的 RESTful 方法已经成为最常见的替代方法。可以使用各种语言(比如 Java 程序、Perl、Ruby、Python、PHP 和 Javascript[包括 Ajax])实现客户端。RESTful Web 服务通常可以通过自动客户端或代表用户的应用程序访问。但是,这种服务的简便性让用户能够与之直接交互,使用它们的 Web 浏览器构建一个 GET URL 并读取返回的内容。


在 REST 样式的 Web 服务中,每个资源都有一个地址。资源本身都是方法调用的目标,方法列表对所有资源都是一样的。这些方法都是标准方法,包括 HTTP GET、POST、PUT、DELETE,还可能包括 HEADER 和 OPTIONS。


在 RPC 样式的架构中,关注点在于方法,而在 REST 样式的架构中,关注点在于资源 —— 将使用标准方法检索并操作信息片段(使用表示的形式)。资源表示形式在表示形式中使用超链接互联。

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台