【架构】Restful API
RESTFUL API
介绍
本质:
基于资源的一种软件架构风格
核心:
面向资源
解决的问题:
降低开发复杂
提高系统可伸缩性
开发一套RESTFUL API可以向所有提供服务
设计概念和准则:
网络上所有事物都可以抽象为资源
每个资源都有唯一资源标示,对资源的操作不会改变这些标示(比如删除行为:删除后的资源标示依然存在,只是资源标示所代表的资源不存在)
所有操作都是无状态的(所有操作都没有关系)
资源:
网络上的实体或具体信息(如文档、音乐、图片…)
Resttful中HTTP协议介绍:
Restful是基于资源的一种软件架构风格,从概念上和HTTP协议无关;但这里说的是Restful API是基于HTTP协议的一种实现,所有内容都根据HTTP协议而来,没有扩充。
HTTP协议 - URL: RFC文档中有详细讲解,这里不做讲解
HTTP是一个属于应用层的协议,特点是简洁快速:
schema://host[:port]/path[?query-string][#anchor]
schema:指定底层使用的协议(如:http https ftp)
host:服务器的IP地址或者域名
port:服务器端口,默认为80(访问HTTPS协议,默认为443)
path:访问资源的路径
query-string:发送给http服务器的数据,一般对资源做筛选操作
anchor:项目代码中的锚链接,定位到特定的章节
HTTP协议 - 请求 (很重要!)
组成格式:请求行、消息报头、请求正文
1.请求行:Method Request-URI HTPP-Version CRLF
举例:GET/HTTP/1.1 CRLF (http基本是1.1版本)
2.请求方法:(RESTFUL API外,仅GET和POST常用)
- GET (获得请求)请求获取Request-URL所标示的资源
- POST (发送数据)在Request-URL所标示的资源后附加新的数据
- HEAD (获取基本信息如创建时间、最后修改时间)请求获取由Request-URI所标示的资源的相应消息报头
- PUT (更新资源)请求服务器存储一个资源,并用Request-URI作为其标示
- DELETE (很少用,但RestfulAPI中常用,因对资源的操作都是增删改查)请求服务器删除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 //请求资源不存在
//5开头一般是服务器自身错误 - 500 Internal Server Error //服务器发生不可预期的错误
- 503 Server Unavailable //服务器当前不能处理客户端的请求(服务器性能达到瓶颈)
RESTful架构与其他架构的区别
SOAP WebService:
WebService是一种跨编程语言和跨操作平台的远程调用技术;
通过HTTP协议发送请求和接受结果时采用XML格式封装,并增加了一些特定的HTTP消息头,这些特定的HTTP消息头和XML内容格式就是SOAP协议。
效率和易用性:
SOAP由于各种需求和不断扩充本身协议的内容,导致SOAP处理方面的性能有所下降,易用性方面和学习成本也有所增加。
RESTful由于其面向资源接口设计以及操作抽象简化了开发者的不良设计,同时也最大限度地利用了HTTP最初的应用协议设计理念。
安全性:
SOAP:成熟型可以给需要提供多语言开发、对于安全性要求很高的接口设计带来便利。作者个人觉得纯粹说设计模式将会占据主导地位没什么意义,关键看应用场景。
RESTful:对于资源型服务接口来说很合适,同时特别适合对于效率要求很高,但是对于安全要求不高的场景。
如何设计RESTful API
1.资源路径 URI:
RESTful结构中。每个网址代表一种资源,所以网址中不能有动词,只能有名词。一般来说API中名词应用负数。
如:https://api.example.com/v1/zoos //动物园资源
https比http安全;后期可能更改版本号,所以加上V1;
2.HTTP动词:对于资源的操作(CURD),由HTTP动词(谓词)表示:
- GET:从服务器取出资源(一项或多项
- POST:在服务器新建一个资源
- PUT:在服务器更新资源(客户端提供改变后的完整资源
- PATCH(少用,更新资源一般用PUT):在服务器更新资源(客户端提供改变的属性
- DELETE:从服务端删除资源
举例:
POST /zoos 新建一个动物园
GET /zoos/ID 获取某个指定动物园的信息
PUT /zoos/ID 更新某个指定动物园的信息
DELETE /zoos/ID 删除某个动物园
3.过滤信息:如果记录数量很多,服务器不可能都将他们返回给客户;
API应该提供参数,过滤返回结果。
举例:
?offset=10:指定返回记录的开始位置
?page=2&per_page=100:指定第几页,以及每页的记录数
?sortby=name&order=asc:指定返回结果排序,以及排序顺序
?animal_type_id=1:指定筛选条件
4.状态码:服务器向用户返回的状态码和提示信息,使用标准HTTP状态码
如:
200 OK 服务器成功返回用户请求的数据,该操作是幂等的
201 CREATED 新建或修改数据成功(平时少用,HTTP中有规定)
204 NO CONTENT 删除数据成功(删除无响应体)
400 BAD REQUEST 用户发出的请求有错误,该操作时幂等的
401 Unauthorized 表死用户没有认证,无法进行当前操作
403 Forbidden 表示用户访问是被禁止的
422 Unprocesable Entity 当创建一个对象时,发生一个验证错误
500 INTERNAL SERVER ERROR 服务器发生错误,用户将无法判断发出的请求是否成功
5.错误处理:
如果状态码是4xx或5xx,就应该向用户返回出错信息。一般来说,返回的信息中将error作为键名,出错信息作为键值即可。{ "error":"参数错误" }
(若是500错误,就不建议返回参数错误,会将服务器本身错误暴露给用户)
6.返回结果: