一、RESTful API简介
1.1 RESTful API是什么
RESTful API全称是Resource Representational State Transfer(资源表述性状态转移)。
R:Resource 资源。例如:user、role、gist、issue、service、route
E:Representational 表述性。数据的表现形式,例如:JSON、XML、CSV、IMG等
S:State 状态。资源的状态,例如:创建、更新等状态
T:Transfer 转移。通过HTTP METHOD,例如:GET、POST、PUT、PATCH、DELETE
RESFful并没有创造任何新的技术或者服务,它是一种架构设计风格,包含一系列的约束条件和原则,只要架构符合该约束条件和原则,我们就称它为RESTful架构。
1.2 为什么使用Restful API
因为它将一个应用的资源、行为、状态都统一到一个设计体系下,API的定义更符合人的认知。在面对一个符合Restful API的未知应用时,你可以很清楚知道,先了解有整个系统有那些资源对象和他们之间的关系,进一步了解资源有哪些行为(在有限的范围内,例如GET、POST、PUT),然后就可以掌握对整个系统的认识和使用,进一步可以构建HATEOAS体系。
反之,非RESTful API则需要查看所有API文档,即便如此,查看后也无法掌握整个系统,因为你不知道有那些可操作性对象,同时一个API也可能包含相反的操作(例如删除一些记录,同时又创建了许多记录)和多个面向对象。
二、标准Restful API
2.1 协议
API与用户通信协议,总是使用HTTPS协议。
//正确示例
https://{api}.restful.com
//错误示例
http://{api}.restful.com
2.2 域名
API应尽量使用专有域名和基路径。
//正确示例
https://{api}.restful.com/api
//错误示例
https://{api}.restful.com/api
2.3 版本
第一种方式,将API的版本号放入URL中。
//正确示例
https://{api}.restful.com/api/v1/routes
//错误示例
https://{api}.restful.com/v1/api/routes
https://{api}.restful.com/api/routes/v1
第二种方式,将API的版本号放入HTTP头信息中。
//正确示例
version: v1
https://{api}.restful.com/api/routes
//错误示例
https://{api}.restful.com/api/routes
2.4 资源
在RESTful架构中,每一个网址代表一种资源。所有网址中不能有动词,只能用名词;通常名词往往与数据库的表相对应;因为数据库的表是记录的合集,所以名词应使用复数形式。
//正确示例
https://{api}.restful.com/api/v1/routes
https://{api}.restful.com/api/v1/services
https://{api}.restful.com/api/v1/users
//错误示例
https://{api}.restful.com/api/v1/route
https://{api}.restful.com/api/v1/getService
https://{api}.restful.com/api/v1/user/disable
问题一:
思考一个问题,实际编码中不一定都是对一个字段的简单CURD,对于复杂API该如何设计:
(1)假设一个job需要开启或关闭,该如何设计?
可以将操作变成一个字段的属性,比如job增加一个enable属性,接口如下:
//开启任务
PATCH /jobs/{jobId}
{
"enable":true
}
//关闭任务
PATCH /jobs/{jobId}
{
"enable":false
}
(2)假设对某个用户的某个任务进行设置,该如何设计?
可以通过用户ID先检索用户资源,再通过任务ID找该用户资源下的任务。
//示例
PUT /users/{userId}/jobs/{jobId}
(3)假设对某个用户关注或取消关注,该如何设计?
可以仿照Github的设计,将关注、点赞也看做是一种抽象的资源,从而可以看做,对某个用户的附属资源进行操作。
//关注
PUT /users/{userId}/following
//取消关注
DELETE /users/{userId}/following
(4)假设登录、登出这种行为呢,该如何设计RESTful API?
可以考虑将登录获得的东西进行资源模拟,例如:
//登录的目的是为了创建token,所以登录可以写成如下形式
POST /token
//登出的目的是为了删除token,所以登出可以写成如下形式
DELETE /token/{token}
2.5 资源的表述
资源是数据,它可以有不同的表现形式,我们把它称为资源的表述。例如数据库中的二进制数据,用户可以根据需要获得JSON、CSV、XML、Excel等不同格式。
客户端可以通过Accept请求头指定资源的表述,服务端则通过Content-Type响应头响应返回的资源格式。
//请求
GET https://{api}.restful.com/api/v1/routes
Accept: application/json
//响应
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"name":"root route",
"path":"/api/group/**",
"to":"/api/**"
}
2.6 操作行为
常用的HTTP操作行为有下面五个(括号中是一般对应的SQL命令)
- GET(SELECT):从服务器获得资源
- POST(CREATE):在服务器新建一个资源
- PUT(UPDATE):在服务器更新资源;在服务器更新或创建资源(客户端提供改变后的完整资源)
- PATCH(UPDATE):在服务器更新资源(客户端提供改变的部分资源)
- DELETE(DELETE):从服务器删除资源(也可能是逻辑删)
//获得所有路由信息
GET https://{api}.restful.com/api/v1/routes
//获得指定路由信息
GET https://{api}.restful.com/api/v1/routes/{routeId}
//获得指定服务的指定路由信息
GET https://{api}.restful.com/api/v1/services/{routeId}/routes/{routeId}
//创建一个路由信息
POST https://{api}.restful.com/api/v1/routes
//更新或创建路由信息(全部)
PUT https://{api}.restful.com/api/v1/routes
//更新路由信息(部分)
PATCH https://{api}.restful.com/api/v1/routes
//删除(也可以是逻辑删)
DELETE https://{api}.restful.com/api/v1/routes/{routeId}
2.7 过滤
如果资源数量很多,用户可能需要过滤返回结果。
下面是一些常见参数。
- ?pageIndex=1&pageSize=10:返回第一页,每页返回10条记录。
- ?sortby=num&order=asc:指定结果按照那个字段排序,以及排序顺序。
- ?type=1:获得类型是1的自数据集合
2.8 状态码
服务器向用户返回的状态码和提示信息,常见的有以下一些(方括号中是该状态码对应的HTTP动词)。
200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。
201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
204 NO CONTENT - [DELETE]:用户删除数据成功。
400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。
401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。
404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。
406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。
410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。
422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。
500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。
2.9 HATEOAS
HATEOAS又叫做Hypermedia API,超媒体API通俗理解就是,API的返回结果中包含下一步可以调用那些API。通常包括与当前API的关系、API的路径、API的描述、返回类型、请求类型。
例如:
{"link": {
"rel": "collection",
"href": "https://{api}.restful.com/api/v1/routes/{routeId}/auths",
"title": "auths of route",
"type": "application/json",
"method":"get"
}}
三、简化Restful API
3.1 状态码
我们调整和简化了Restful API状态码的返回,因为我们需要更加详细的描述异常问题。
(1)API都应使用HTTP状态码 200(OK) 响应客户端请求
(2)API都采用JSON结构请求和返回
(3)返回结果符合以下结构
{
"success": false, //ture成功,false失败
"code": 10000, //错误码
"message": "", //错误描述
"value": {} //值
}
3.2 不支持
相对于标准RESTful API,不支持以下特性:
(1)HTTP状态码
(2)HATEOAS
本文详细介绍了RESTful API的概念及其优势,强调了标准RESTful API的规范,如使用HTTPS协议、专有域名、版本控制、资源表述、操作行为、过滤和状态码。同时,提供了复杂API设计示例,如任务开启/关闭、用户任务设置、关注/取消关注、登录/登出。还探讨了简化RESTful API时对状态码的调整和返回结果的统一格式。最后,提及了HATEOAS的概念,并给出了参考链接。


7493

被折叠的 条评论
为什么被折叠?



