Restful是什么
- 本质:一种软件架构风格
- 核心:面向资源
- 资源:网络上的一个实体,网络上的一个具体信息
- 解决的问题:1、降低开发的复杂性;2、提高系统的可伸缩性
也可以总结为一句话:Restful是所有Web应用都应该遵守的架构设计指导原则。
Restful中HTTP协议介绍
http协议-url
http是一个属于应用层的协议,特点是简捷、快速。
schema://host[:port]/path[?query-string][#anchor]
- ==scheme== 指定低层使用的的协议(例如:http,https,ftp)
- ==host== 服务器的IP地址或域名
- ==port== 服务器端口,默认为80
- ==path== 访问资源的路径
- ==query-string== 发送给http服务器的数据
- ==anchor== 锚
http协议-请求
组成格式:请求行、消息报头、请求报文
请求行
- 格式如下:Method Request-URL HTTP-Version CRLF
举例
- GET / HTTP/1.1 CRLF
请求方法
- ==GET== 请求获取Requesr-URI所标识的资源
- ==POST== 在Request-URI所标识的资源后附加薪的数据
- ==HEAD== 请求获取由Request-URI所标识的资源的响应消息报头
- ==PUT== 请求服务器存储一个资源,并用Request-URI作为其标识
- ==DELETE== 请求服务器删除Request-URI所标识的资源
- ==OPTIONS== 请求查询服务器的性能,或者查询与资源相关的选项和需求
http协议-响应
组成格式:状态行、消息报头、响应正文
状态行
- HTTP-Version Status-Code Reason-Phrase CRLF
- 例如:HTTP /1.1 200 OK
常用状态码
- 200 OK //客户端请求成功
- 400 Bad Request //客户端请求有语法错误,不能被服务器所理解
- 401 Unauthorized //服务器收到请求,但是拒绝提供服务
- 404 Not Found //请求资源不存在
- 500 Internal Server Error //服务器发送不可预期的错误
- 503 Server Unavailable //服务器当前不能处理客户端的请求
Restful架构与其他架构的区别
SOAP WebService
- WebService是一种跨编程语言和跨操作系统平台的远程调用技术。
- WebService通过HTTP协议发送请求和接收结果时采用XML格式封装,并增加了一些特定的HTTP消息头,这些特定的HTTP消息头和XML内容格式就是SOAP协议。
效率和易用性
SOAP由于各种需求不断扩充其本身协议的内容,导致在SOAP处理方面的性能有所下降。同时在易用性方面以及学习成本上也有所
增加。Restful由于其面向资源接口设计以及操作抽象简化了开发者的不良设计,同时也最大限度
的利用了Http最初的应用协议设计理念。安全性
Restful对于资源型服务接口来说很合适,同时特别适合对于效率要求很高,但是对于安全要求不高的场景。
SOAP的成熟性可以给需要提供给多开发语言的,对于安全性要求较高的接口设计带来便利。所以我觉得纯粹说什么设计模式将会占据主导地位没有什么意义,关键还是看应用场景。
如何设计Restful 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 | https://api.example.com/v1/zoos |
HTTP动词
对于资源的具体操作类型,由HTTP动词表示。
常用的HTTP动词有下面五个(括号里是对应的SQL命令)。
1 | GET(SELECT):从服务器取出资源(一项或多项)。 |
还有两个不常用的HTTP动词。
1 | HEAD:获取资源的元数据。 |
下面是一些例子。
1 | GET /zoos:列出所有动物园 |
过滤信息(Filtering)
如果记录数量很多,服务器不可能都将它们返回给用户。API应该提供参数,过滤返回结果。
下面是一些常见的参数。
1 | ?limit=10:指定返回记录的数量 |
参数的设计允许存在冗余,即允许API路径和URL参数偶尔有重复。比如,GET /zoo/ID/animals 与 GET /animals?zoo_id=ID 的含义是相同的。
状态码(Status Codes)
服务器向用户返回的状态码和提示信息,常见的有以下一些(方括号中是该状态码对应的HTTP动词)。
1 | 200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。 |
状态码的完全列表参见这里。
错误处理(Error handling)
如果状态码是4xx,就应该向用户返回出错信息。一般来说,返回的信息中将error作为键名,出错信息作为键值即可。
1 | { |
返回结果
针对不同操作,服务器向用户返回的结果应该符合以下规范。
1 | GET /collection:返回资源对象的列表(数组) |
Hypermedia API
RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。
比如,当用户向api.example.com的根目录发出请求,会得到这样一个文档。
1 | {"link": { |
上面代码表示,文档中有一个link属性,用户读取这个属性就知道下一步该调用什么API了。rel表示这个API与当前网址的关系(collection关系,并给出该collection的网址),href表示API的路径,title表示API的标题,type表示返回类型。
Hypermedia API的设计被称为HATEOAS。Github的API就是这种设计,访问api.github.com会得到一个所有可用API的网址列表。
1 | { |
从上面可以看到,如果想获取当前用户的信息,应该去访问api.github.com/user,然后就得到了下面结果。
1 | { |
上面代码表示,服务器给出了提示信息,以及文档的网址。
HTTP其他
- API的身份认证应该使用OAuth 2.0框架。
- 服务器返回的数据格式,应该尽量使用JSON,避免使用XML。
参考资料
Restful API实战
RESTful API 设计指南
理解RESTful架构
RESTful API 设计参考文献列表