RESTFul风格的接口

RESTFul风哥的接口

  • 网络应用程序,分为前端和后端两个部分。当前的发展趋势,就是前端设备层出不穷(手机、平板、桌面电脑、其他专用设备等等)。
  • 因此,必须有一种统一的机制,方便不同的前端设备与后端进行通信。这导致API构架的流行,甚至出现”API First”的设计思想。RESTful API是目前比较成熟的一套互联网应用程序的API设计理论。

    一、协议

    API与用户的通信协议,总是使用HTTPs协议。

二、域名

应该尽量将API部署在专用域名之下。

1
https://api.example.com

如果确定API很简单,不会有进一步扩展,可以考虑放在主域名下。

1
https://example.org/api/

三、版本(Versioning)

应该将API的版本号放入URL。

1
https://api.example.com/v1/

  • 另一种做法是,将版本号放在HTTP头信息中,但不如放入URL方便和直观。Github采用这种做法。

    四、路径(Endpoint)

  • 路径又称”终点”(endpoint),表示API的具体网址。
  • 在RESTful架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词,而且所用的名词往往与数据库的表格名对应。一般来说,数据库中的表都是同种记录的”集合”(collection),所以API中的名词也应该使用复数。
  • 举例来说,有一个API提供动物园(zoo)的信息,还包括各种动物和雇员的信息,则它的路径应该设计成下面这样。
    1
    2
    3
    https://api.example.com/v1/zoos
    https://api.example.com/v1/animals
    https://api.example.com/v1/employees

五、HTTP动词

  • 对于资源的具体操作类型,由HTTP动词表示。
  • 常用的HTTP动词有下面五个(括号里是对应的SQL命令)。

    1
    2
    3
    4
    5
    6
    7
    8
    GET(SELECT):从服务器取出资源(一项或多项)。
    POST(CREATE):在服务器新建一个资源。
    PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
    PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
    DELETE(DELETE):从服务器删除资源。
    还有两个不常用的HTTP动词。
    HEAD:获取资源的元数据。
    OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的。
  • 下面是一些例子。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    GET /zoos:列出所有动物园
    POST /zoos:新建一个动物园
    GET /zoos/ID:获取某个指定动物园的信息
    PUT /zoos/ID:更新某个指定动物园的信息(提供该动物园的全部信息)
    PATCH /zoos/ID:更新某个指定动物园的信息(提供该动物园的部分信息)
    DELETE /zoos/ID:删除某个动物园
    GET /zoos/ID/animals:列出某个指定动物园的所有动物
    DELETE /zoos/ID/animals/ID:删除某个指定动物园的指定动物
    ```
    ### 六、过滤信息(Filtering)
    * 如果记录数量很多,服务器不可能都将它们返回给用户。API应该提供参数,过滤返回结果。
    * 下面是一些常见的参数。
    ``` bash
    ?limit=10:指定返回记录的数量
    ?offset=10:指定返回记录的开始位置。
    ?page=2&per_page=100:指定第几页,以及每页的记录数。
    ?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。
    ?animal_type_id=1:指定筛选条件
  • 参数的设计允许存在冗余,即允许API路径和URL参数偶尔有重复。比如,GET /zoo/ID/animals 与 GET /animals?zoo_id=ID 的含义是相同的。

七、状态码(Status Codes)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
  1xx为消息类,该类状态码用于表示服务器临时回应。
    100 continue 表示出的请求已经被服务器接收,游览器应当继续发送请求的其余部分(HTTP1.1)

    101 switching pototcols 服务器将遵从客户的请求转换到另外一种协议(HTTP1.1)。

  2xx 表示浏览器端请求被处理成功#
    200 ok 一切正常

    201 created 服务器已经创建了文档,location 头给出了他的URL。

    202 accepted 已经接收请求,但是尚未处理完成。

    203 non-authoritative information 文档已经正常的返回,但一些应答头可能不正确,因为使用的是的文档的拷贝(HTTP 1.1新)。

    204 no content 没有新文档,游览器应该继续显示原来的文档,这个跟下面的304非常相似。

    205 Reset content 没有新的内容,到那时游览器应该重置它所显示的内容,用来强制清楚表单输入内容(HTTP1.1 新)

    206 partial content 客户发送了一个带有range头的GET请求,服务器完成了它(HTTP1.1 新)。注意 通过Range 可以实现断点续传。

  3xx 重定向。#
    300 Multiple choices 客户请求的文档可以在多个位置找到,这些位置已经在返回的文档内列出,如果服务器要提出优先选择,则应该在location 应答头指明。

    301 Mulitiple permanently 客户请求的文档在其他地方,新的url在location 头中给出,浏览器应该自动的访问新的URL。

    302 Found 类似301,但新的URL应该被视为临时性的替代,而不是永久性的,注意,在HTTP1.0中对应的状态信息moved Temporatily。出现该状态码,浏览器能够给自动访问新的URL,因此他是一个很有用的状态代码。

    注意这个状态代码有时候可以和301替换使用,例如,如果浏览器错误的请求http:// host/~user(缺少了后面的斜杠,有的服务器返回301,有的返回302)。严格的说,我们只能假定原来的请求是GET时浏览器才会自动重定向。

    303 see other 类似于301/302,不同之处在于,如果原来的请求是post,location头指定的重定向目标文档应该通过get提取(http 1.1 新)。

    304 not modified 客户端有缓冲的文档并发出了一个条件性的请求(一般是提供if -modified -since 头表示客户端执行比指定日期更新的文档)。服务器告诉客户,原来缓冲的文档还可以继续使用。

    305 use proxy 客户请求的文档应该通过location 头所指明的代理服务器提取(HTTP 1.1新)。

    307 temporary redirect 和302(found)相同,许多浏览器会错误的相应302应该进行重定向,即使原来的请求是post,即使它实际上只在post请求的应答是303时,才能重定向。由于这个原因,HTTP1.1新增了307,以便更加清楚的区分几个状态代码,当出现303应答时,浏览器可以跟随重定向的get和post请求,如是307应答,则浏览器只能跟随对get的请求的重定向。

  400 错误#
    400 Bad Request 请求出现语法错误。

    401 unauthorized 客户试图未经授权访问受密码保护的页面。应答中会包含-WWW-Authenticate头,浏览器据此显示用户名字和密码对话框,然后再填写合适的authorization头后再次发送请求。

    403 Forbidden 资源不可用。服务器理解客户的需求,但是拒绝处理他通常由于服务器上文件或目录的权限设置问题。

    404 NO Found 无法找到指定位置的资源,也是一个常用的应答。

    405 Method not allowed 请求方法(GET、POST、HEAD、Delete、put、trace等)对指定的资源不适用。(HTTP 1.1新)

    406 not acceptable 指定的资源已经找到,但是mime类型和客户在accpet头中所指定的不兼容(HTTP 1.1新)

    407 proxy authentication reqired 类似于401 ,表示客户必须先经过代理服务器的授权。(HTTP 1.1新)

    408 request timeout 在服务器许可的等待时间内,客户一直没有发出任何请求。客户可以在以后重复同一请求。(HTTP 1.1新)

    409 conflict 通常和put 请求有关,由于请求和资源的当前状态相冲突,因此请求不能成功(HTTP 1.1新)

    410 Gone 所请求的文档已经不在可用,而且服务器不知道应该重新到哪一个地址,他和404的不同在于,返回407表示文档永久的离开了指定的位置,而404表示由于位置的原因文档不可用。(HTTP 1.1新)

    411 length required 服务器不能处理请求,除非客户发送一个contene-length头(HTTP 1.1新)

    412 preconfition Failed请求头中指定的一些前提条件失败(HTTP 1.1新)

    413 request entity too large 目标文档的大小超过服务器当前原意处理的大小。如果服务器认为自己能够稍后再处理请求,则应该提供一个retry-After头(HTTP 1.1新)

    414 Request URL Too loog URL太长( HTTP 1.1新)

    416 required range not satisfiable 服务器不能满足客户在请求中的指定range 头(HTTP 1.1新)

  5xx服务器错误#
    500 internal Server Error 服务器遇到了意料不到的情况,不能完成客户的请求

    501 Not lmplemented 服务器不支持请求所需要的功能。例如,客户发出来了一个服务器不支持的put请求。

    502Bad Gateway 服务器作为网关或者代理时,为了完成请求访问下一个服务器,但该服务器返回了非法的应答。

    503 service unavilable 服务器由于维护或者负载过重未能应答。例如,servlet 可能在数据库连接池已满的情况下返回503.服务器返回503时可以提供一个retry-after头。

    504 gateway timeout 作为代理或网关服务器使用,表示不能及时的从远程服务器获得应答(HTTP 1.1新)

    505 HTTPversion not supported 服务器不支持请求中所指明的HTTP版本。(HTTP 1.1新)
八、错误处理(Error handling)
如果状态码是4xx,就应该向用户返回出错信息。一般来说,返回的信息中将error作为键名,出错信息作为键值即可。
{error: "Invalid API key" }
```

### 九、返回结果
``` bash
GET /collection:返回资源对象的列表(数组)
GET /collection/resource:返回单个资源对象
POST /collection:返回新生成的资源对象
PUT /collection/resource:返回完整的资源对象
PATCH /collection/resource:返回完整的资源对象
DELETE /collection/resource:返回一个空文档
```
### 十、Hypermedia API
* RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。比如,当用户向api.example.com的根目录发出请求,会得到这样一个文档。
``` bash
{"link": { "rel": "collection https://www.example.com/zoos", "href": "https://api.example.com/zoos", "title": "List of zoos", "type": "application/vnd.yourformat+json" }}
```
*上面代码表示,文档中有一个link属性,用户读取这个属性就知道下一步该调用什么API了。rel表示这个API与当前网址的关系(collection关系,并给出该collection的网址),href表示API的路径,title表示API的标题,type表示返回类型。Hypermedia API的设计被称为HATEOAS。Github的API就是这种设计,访问api.github.com会得到一个所有可用API的网址列表。
``` bash
{ "current_user_url": "https://api.github.com/user", "authorizations_url": "https://api.github.com/authorizations", // ...
}
```
* 从上面可以看到,如果想获取当前用户的信息,应该去访问api.github.com/user,然后就得到了下面结果
``` bash
{ "message": "Requires authentication", "documentation_url": "https://developer.github.com/v3" }
  • 上面代码表示,服务器给出了提示信息,以及文档的网址。

    十一、其他

  • (1)API的身份认证应该使用OAuth 2.0框架。
  • (2)服务器返回的数据格式,应该尽量使用JSON,避免使用XML。
  • RESTful的优点:
    • 可更高效利用缓存来提高响应速度
    • 通讯本身的无状态性可以让不同的服务器的处理一系列请求中的不同请求,提高服务器的扩展性
    • 浏览器即可作为客户端,简化软件需求
    • 相对于其他叠加在HTTP协议之上的机制,REST的软件依赖性更小
    • 不需要额外的资源发现机制
    • 在软件技术演进中的长期的兼容性更好
分享到