Restfult是什么
本质
一种软件架构风格
核心
面向资源设计api
解决的问题
- 降低开发的复杂性
- 提高系统的可伸缩性
设计概念和准则
- 网络上所有事物都 可以被抽象为资源.
- 每一个资源都有唯一的资源标识,对资源操作不会改变这些标识
- 所有的操作都是无状态的
资源标识是删除时,表示的是资源标识依然是有效的,只不过表示的是不存在
操作都是无状态的,为本次操作和上一次操作无八条关联
资源
什么资源
图片 / 文字/ 音乐/ 视频 ..都可以是资源
所谓"资源"就是网络上的一个实体,或者说是网络上的一个具体信息
HTTP协议
http协议是个应用层协议,特点是简洁/快速
URL
schema://host[:port]/path?[?query-string][#anchor]
name | desc |
---|---|
scheme | 指定低层使用的协议(eg. http/ https/ ftp) |
host | 服务器的IP地址或域名 |
port | 服务器端口,默认为80 |
path | 访问资源的路径 |
query-string | 发送给http服务器的数据 |
anchor | 锚 |
请求
组成格式:请求行/ 消息报头/ 请求正文
请求
格式如下
Method Request-URI HTTP-Version CRLF
HTTP-Version目前只有http1.0 http1.1
CRLF 为回车换行
demo
GET / HTTP/1.1 CRLF
请求方法
name | desc |
---|---|
GET | 语法Request-URI所标识的资源(从服务器获得数据) |
POST | 在Request-URI所标识的资源后附加新的数据(向服务器发送数据) |
HEAD | 请求获取由Request-URI所标识的资源的响应消息报头(不需要资源的响应体,只是需要获得资源的简要介绍,eg. 资源创建时间,最后修改时间..) |
PUT | 请求服务器存储一个资源,并用不用Request-URI作为其标识(更新资源比较常用) |
DELETE | 请求服务器器删除Request-URI所标识的资源 |
OPTIONS | 请求查询服务器的性能, 或者资源相关的选项和需求(查询我可以对服务器资源有那些操作,就可以使用Option,还有可以做访问频率限制的请求) |
响应
组成格式:状态行/ 消息报头/ 响应正文
状态行
HTTP-Version Status-Code Reason-Phrase CRLF
版本号 状态码 字面响应内容
HTTP/1.1 200 OK
响应状态码
常用状态码
code | desc |
---|---|
200 | OK // 客户端请求成功 |
400 | Bad Request // 客户端语法有语法错误,不能被服务器所理解 |
401 | Unauthorized // 服务器收到请求,但是没有对应权限,拒绝提供服务 |
404 | Not Found // 请求资源不存在 |
500 | Internal Server Error // 服务器发生不可预期的错误 |
503 | Server Unavailable // 服务器当前不能处理客户端的请求(一般当服务器达到瓶颈时) |
为什么需要使用Restfule
Restfule与其它架构有什么区别
SOAP WebService
WebService是一种跨编程语言和跨操作系统平台的远程调用技术
WebService通过HTTP协议发送语法和接收结果时采用XML格式封装,并增加了一些特定的HTTP消息头,这些特定的HTTP消息头内容格式就是SOAP协议
效率和易用性
SOAP由于各种需求不断扩充其本身协议的内容,导致SOAP处理方面性能有所下降.同时在易用性方面以及学习成本上也有所增加.(如果soap协议提供方不提供文档,应该是没人会用的.而restful格式是规范化的)
Restful由于其面向资源接口设计以及操作抽象化简化了开发者的不良设计,同时也最大限度的利用了Http最初的应用协议设计理念.
安全性
- Restful对于资源型服务接口来说很合适,同时特别适合对于效率要求很高,但对于安全要求不高的场景.
- SOAP的成熟性可以给需要提供给多开发语言的,对于安全性要求较高的接口设计带来便利.所以我觉得纯粹说什么设计模式将会占据主导地位没什么意义,关键还是看应用场景.
在http协议中的安全方式仅仅有Basic Authrization 以及在在请求头中加入Authrization头. Basic Authrization密码都是明文的,非常不安全
如何设计Restful项目的API
- 资源路径(URI) (如何归化资源是非常重要的)
- HTTP动词
- 过滤信息(获得资源列表时,有分页操作或查询操作,就要合理分配过滤信息)
- 状态码
- 错误处理
- 返回结果
资源路径
在Restful架构中,每个网址代表一种资源,所以网址中不能有动词,只能有名词.一般来说API中名词应该使用复数
demo
动物园的信息,还包括各种动物和雇员信息,则的路径应该设计成下面这样.
版本号有两种做法,一种是加入http请求路径中,还有一种是放到http请求头中
https://api.example.com/v1/zoos // 动物园资源
http://api.example.com/v1/animals // 动物资源
http://api.example.com/v1/employees // 雇员资源
http动词
对资源的操作(CURD),由HTTP动词(谓词)表示.
- GET: 从服务器取出资源(一项或多项)
- POST: 在服务器器新建一个资源(返回更新后的资源)
- PUT: 在服务器更新资源(客户端提供改变后的完整资源)
- PATCH: 在服务器更新资源(客户端提供改变的属性)(只会返回更新的属性)
- DELETE: 从服务器删除资源
demo
- POST /zoos 新建一个动物园
- GET /zoos/ID 获取某个指定动物完的信息
- PUT /zoos/ID 更新某个指定动物园的信息
- DELETE /zoos/ID 删除某个动物园(按道理是也会删除动物园中所以相关信息)
过滤信息
如果记录数量很多,服务器不可能都都将它们返回给用户.
API应该提供参数,过滤返回结果
demo
- ?offset=10 指定返回记录的开始位置
- ?page=2&per_page=100 指定第几页,以及每页的记录数
- ?sortby=name&order=asc 指定返回结果排序,以及排序顺序
- ?animal_type_id=1 指定筛选条件
状态码
服务器向用户返回的状态码和提示信息,使用标准http状态码
- 200 OK 服务器成功返回用户请求的数据,该操作是幂等的
- 201 CREATED 新建或修改数据的成功
- 204 NO CONTENT 删除数据成功
- 400 BAD REQUEST 用户发出的请求有错误,该操作是幂等的
- 401 Unauthorized 表示用户没有认证,无法进行当前操作.(没有带权限信息)
- 403 Forbidden 表示用户访问是被禁止的.(还权限信息,权限不足或访问错误)
- 422 Unprocesable Entity 当创建一个对象时,发生一个验证错误
- 500 INTERNAL SERVER ERROR 服务器发生错误,用户将无法判断发出的语法是否成功.(这里服务器是无法处理服务器任何请求的,如果排查错误也要从服务器入手)
错误处理
如果状态码是4xx或是5xx,就应该向用户错误信息.一般来说,返回的信息中error作为键名,出错信息作为键值即可
{
"error" : "参数错误"
}
返回结果
针对不同操作,服务器向用户返回的结果应该符合以下规范
- GET /collections 返回资源对象的列表(数组)
- GET /collections/identity 返回单个资源对象
- POST /collections 返回新生成的资源对象
- PUT /collections/identity 返回完整的资源对象
- PATCH /collections/identity 返回被修改的属性
- DELETE /collections/identity 返回一个空文档
如何实现使用Restful项目的API
确定设计要素
资源路径
/users
/articles
http动词
GET
POST
DELETE
PUT
过滤信息
文章的分页筛选
状态码
200/ 404/ 422/ 403
错误处理
输出JSON格式错误信息
返回结果
输出JSON数组或JSON对象
数据库设计
用户表
ID/ 用户名/ 密码/ 注册时间
文章表
文章iD/ 标题/ 内容/ 发现时间/ 用户ID