文章目录

前言

最近发现小伙伴们写的API不仅仅有Get/Post,还有大量的Put/Patch/Delete,其实是有点疑惑的:所有的这些操作使用Post不就都能搞定吗?​事实确实如此,Post能够搞定一切的需求。那为什么还要使用专门的Put、Patch、Delete呢?理由就是为了构建Restful架构。

HTTP/1.1的八种方法

HTTP(HyperText Transfer Protocol,超文本传输协议)是应用层的无状态网络协议,2015年提出了HTTP2.0,但是目前用得最多的还是HTTP1.1。HTTP1.1定义了八种方法来操作资源:

方法 初始来源作用描述
 Get HTTP 1.0

请求指定的页面信息,并返回实体主体。

 Post HTTP 1.0向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。
数据被包含在请求体中。
POST请求可能会导致新的资源的建立和/或已有资源的修改。 
 Head HTTP 1.0

类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头    

 Put HTTP 1.1

从客户端向服务器传送的数据取代指定的文档的内容。

 Delete HTTP 1.1

请求服务器删除指定的页面。

 Connect HTTP 1.1HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
 Options HTTP 1.1

这个方法可使服务器传回该资源所支持的所有HTTP请求方法。

允许客户端查看服务器的性能。

 Trace HTTP 1.1

回显服务器收到的请求,主要用于测试或诊断。

Rest和Restful API

(崩溃,都快写完了死机一下,又得从这里开始重写……)

Rest(Representational State Transfer,表述状态转移)在2000年Roy Fielding的博士论文《Architectural Styles and the Design of Network-based Software Architectures》中首次被提出,指的是一组架构约束条件和原则。符合这些约束条件和原则框架的API就是Restful API。

简单地总结这些约束条件和原则就是,URL定位资源,HTTP动词描述操作

1、资源和表述

通常Web资源可以使用URI(Uniform Resource Identifier,统一资源标识符)来定位,URL是URI的一个子集,URL除了确定资源,还确定了访问方式(是用HTTP呢,FTP呢,还是LDAP呢),例如官方的例子,这些都是URI,但只有部分是URL:

ftp://ftp.is.co.za/rfc/rfc1808.txt (also a URL because of the protocol)
http://www.ietf.org/rfc/rfc2396.txt (also a URL because of the protocol)
ldap://[2001:db8::7]/c=GB?objectClass?one (also a URL because of the protocol)
mailto:John.Doe@example.com (also a URL because of the protocol)
news:comp.infosystems.www.servers.unix (also a URL because of the protocol)
tel:+1-816-555-1212
telnet://192.0.2.16:80/ (also a URL because of the protocol)

Rest对资源的表述具体的约束:

(1)资源的格式

【只能使用名词,不能使用动词】

举个例子,通常的URL会这样设计:

http://www.bewindoweb.com/getArticle?id=1

而Restful API是这样的:

http://www.bewindoweb.com/articles/1

看起来更像是某个资源的位置了,而不管具体的访问方法。

【问号用来过滤】

还是那个例子,我们想要对文章内容分页获取,普通的设计:

http://www.bewindoweb.com/getArticle?id=1&pageNo=1

而Restful API是这样的:

http://www.bewindoweb.com/articles/1?pageNo=1

id并不使用问号,是因为它是资源定位的一部分;pageNo使用问号,是因为在对这个资源进行过滤操作,过滤可以包括pageNo、limit、state=0等等。

【单数和复数】

没有统一规定,但明显复数比单数好,例如articles/1article/1更好,因为文章可能有很多篇。

【版本号】

可以在URL里面加入版本号,如:

http://www.bewindoweb.com/v1/article/1

(2)统一的访问接口

Rest规定使用HTTP统一的Get、Post、Put、Patch、Delete来对资源进行访问。这里多了一个Patch,Patch是2010年RFC5789新增的HTTP请求方式,然而目前大多数容器都不支持,部分浏览器也不支持,HTML4只支持Get/Post,HTML5也增加了Put/Delete而已。所以对于Patch,在处理的时候需要去查询具体的解决方法。在讲述这些接口的作用前,了解两个概念:

【安全性(Safety)】

无论请求多少次,都不会改变服务器的状态。

例如,无论使用Get请求多少次文章,都不会改变文章具体的数据。

【幂等性(Idempotent)】

无论对资源操作多少次,结果总是一样的。

例如,采用PUT提交修改后的文章,无论操作多少次,修改后的文章内容都是一样的;而用POST让银行卡余额减少200,每次POST之后银行卡的余额都会发生变化。

所以,总结一下这5个请求方法:

请求方法 安全性 幂等性 作用
 Get安全幂等获取表示
变更时获取表示(缓存)
 Post不安全不幂等 服务端的实例号创建资源
创建子资源
 Put不安全幂等 客户端的实例号创建资源
替换的方式更新资源
 Patch不安全不幂等 部分更新资源
 Delete不安全幂等删除资源

根据服务端实例号创建资源:POST /items,服务端生成uuid。如果发生问题,服务端会重新生成uuid。

根据客户端实例号创建资源:PUT /items/31a1576d-7149-461a-a631-38bc11a5b2d3,利用幂等特性,无论出现什么问题,uuid不会变。

部分更新资源:Patch user/1 + 参数username=bwb,只需要携带一个参数即可,不需要全部的user属性。

(3)多种表现形式

客户端根据Accept、服务端根据Content-Type来进行协商,可以使用XML、Json等等很多表现形式。

2、资源的链接

资源之间需要链接起来,那么就要求表述格式里面加入链接来引导客户端,例如:

【请求】

GET https://api.bewindoweb.com/articles/1 HTTP/1.1
Accept: application/json

【响应】

HTTP/1.1 Status: 200 OK
Link: <https://api.bewindowb.com/articles/1?page=2>; rel="next",
        <https://api.bewindoweb.com/articles/1?page=3>; rel="last"
Content-Type:application/json; charset=utf-8
[
  {
     .....
  }
]

响应头里面包含了如何访问下一页和尾页的链接。

3、状态和转移

Rest是无状态通信的,每一次请求都看作是全新的请求,是不会存在JSESSIONID这样的Cookie的。服务端只维护资源状态,并不关心客户端的状态(不会保存session);客户端才维护应用状态,所以状态转移指的是客户端的状态转移。

举个例子,如果你想要查询工资,那么你需要经过登录→工资界面→工资数据,这是普通的Session的有状态通信;如果你输入一个URL立刻得到了工资数据,这就是符合Rest要求的架构。

很明显可以看出一个问题是,资源的安全性应该如何保障?目前通用的做法是JWT(JSON Web Token)进行认证和授权。

4、状态码

Rest要求返回具体的状态码,而不是出错返回200,然后再在Json里面描述出错信息。简单列举一些状态码:

状态码 描述 
 200  操作完成(更新成功、删除成功)
 201 新资源被创建
 204 资源为空
 304 没有变化,客户端可以使用缓存
 400 非法调用(参数错误)
 401 未认证
 403 不允许访问
 404 资源不存在
 500 通用错误
 503 服务器当前无法处理请求


总结

Restful API非常适合于分布式服务器提供接口服务,认证逻辑简单,资源控制清晰,可以跨域等等,不需要保存任何会话数据,值得实践。


转载请注明出处http://www.bewindoweb.com/221.html | 三颗豆子
分享许可方式知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议
重大发现:转载注明原文网址的同学刚买了彩票就中奖,刚写完代码就跑通,刚转身就遇到了真爱。
你可能还会喜欢
具体问题具体杠