文章目录
- 前言
- 一、Restful Api是什么?
- 1.Rest是什么?
- 2.Rest设计规范
- (1)、资源。
- (2)、统一资源接口。
- (3)、使用无状态请求模型。
- (4)、URI。
- (5)、URL中使用名词且为复数,尽量不使用动词。
- 3.Restful API的设计原则
- (1)、协议(schema)
- (2)、域名
- (3)、版本 (version)
- (4)、路径(Endpoint)
- (5)、Http动词
- (6)、过滤信息(Filtering)
- (7)、状态码(Status Code)
- (8)、异常处理(Error handing)
- (9)、预期返回结果
- (10)、认证 (Authentication)
前言
提示:以下是本篇文章正文内容,下面案例可供参考
一、Restful Api是什么?
Restful api是一种软件架构风格;主要面向资源;可以降低开发的复杂性,提高系统的可伸缩性。在理解Restful api前先了解Rest:
1.Rest是什么?
Rest(Representation State transfer):表述性状态转移;那究竟指的是什么的表述呢?其实指的就是资源,任何事物,只要有被引用的必要,都可以称为资源,资源可以是实体,也可以是一个抽象概念;当然一个资源要可以被识别,必须有一个唯一标识,在Web中这唯一标识就是URI;(简单的说是使用URI来表示资源,通过Http的GET、POST、PUT、DELETE方法对资源进行操作。)
URI(Uniform Resource Identifier):标记资源的唯一标识;既可以看成是资源的地址,也可以看成是资源的名称。如果某些信息没有使用URI来表示,那它就不能算是一个资源, 只能算是资源的一些信息而已。URI的设计应该遵循可寻址性原则,具有自描述性,需要在形式上给人以直觉上的关联。
2.Rest设计规范
(1)、资源。
首先要明确资源就是网络上的一个实体,可以是文本、图片、音频、视频。资源总是以一定的格式来表现自己。文本用txt、html;图片用JPG、JPEG等等。而JSON是RESTful API中最常用的资源表现格式。
(2)、统一资源接口。
RESTful架构遵循统一接口原则,统一接口包含了一组受限的预定义的操作,不论什么样的资源,都是通过使用相同的接口进行资源的访问。如果按照HTTP方法的语义来暴露资源,那么接口将会拥有安全性和幂等性的特性,例如GET和HEAD请求都是安全的, 无论请求多少次,都不会改变服务器状态。而GET、HEAD、PUT和DELETE请求都是幂等的,无论对资源操作多少次, 结果总是一样的,后面的请求并不会产生比第一次更多的影响。(简单来讲对于业务数据的CRUD,RESTful 用HTTP方法与之对应。)
(3)、使用无状态请求模型。
HTTP 请求应该是独立的,并且可以以任何顺序发生,因此保持请求之间的瞬态信息是不可行的。唯一存储信息的地方是资源本身,每个请求都应该是一个原子操作。此约束使 Web 服务具有高度可扩展性,因为不需要保留客户端和特定服务器之间的任何关联。任何服务器都可以处理来自任何客户端的任何请求。也就是说,其他因素可能会限制可扩展性。例如,许多 Web 服务写入后端数据存储,这可能难以横向扩展。
(4)、URI。
URI,统一资源标识符,它可以唯一标识一个资源。注意到,URL(统一资源定位符)是一种URI,因为它可以唯一标志资源。但URL != URI。应该说URL 是URI的子集。因为URL使用路径来唯一标识资源,这只是唯一标识资源的一种方式。还可以用一个唯一编号来标识资源,如example.html.fuce2da23。只不过这种方式并不被广泛使用。总之,要在概念上对URL和URI有所区分。
(5)、URL中使用名词且为复数,尽量不使用动词。
这是因为在REST要求对资源的操作由HTTP 方法给出,而方法是由HTTP 请求报文头部给出的,自然不需要在URL中暴露操作方式。(不符合CRUD的,可以使用动词)
其实Restful API 就是基于REST风格的API,接下来了解下Restful API
3.Restful API的设计原则
(1)、协议(schema)
API与用户的通信协议,总是使用HTTPs协议。
(2)、域名
应该尽量将API部署在专用域名之下。
https://api.example.com
如果确定API很简单,不会有进一步扩展,可以考虑放在主域名下。
https://api.example.com/api
(3)、版本 (version)
应该将API的版本号放入URL。另一种做法是,将版本号放在HTTP头信息中,但不如放入URL方便和直观。Github采用这种做法。
https://api.example.com/v1/
https://api.example.com/v2/
(4)、路径(Endpoint)
路径又称"终点"(endpoint),表示API的具体网址。在RESTful架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词,而且所用的名词往往与数据库的表格名对应。一般来说,数据库中的表都是同种记录的"集合"(collection),所以API中的名词也应该使用复数。
https://api.example.com/v1/apples
https://api.example.com/v1/peers
(5)、Http动词
对于资源的具体操作类型,由HTTP动词表示。
GET(SELECT):从服务器取出资源(一项或多项)。
POST(CREATE):在服务器新建一个资源。
PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
DELETE(DELETE):从服务器删除资源。
还有两个不常用的动词:
HEAD:获取资源的元数据。
OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的。
(6)、过滤信息(Filtering)
如果记录数量很多,服务器不可能都将它们返回给用户。API应该提供参数,过滤返回结果。
常见的参数如下:
https://api.example.com/v1/peers?limit=10:指定返回记录的数量
https://api.example.com/v1/peers?offset=10:指定返回记录的开始位置。
https://api.example.com/v1/peers?page=2&per_page=100:指定第几页,以及每页的记录数。
https://api.example.com/v1/peers?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。
https://api.example.com/v1/peers?animal_type_id=1:指定筛选条件
(7)、状态码(Status Code)
服务器向用户返回的状态码和提示信息,常见的有以下一些(方括号中是该状态码对应的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 - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。
(8)、异常处理(Error handing)
如果状态码是4xx,就应该向用户返回出错信息。一般来说,返回的信息中将error作为键名,出错信息作为键值即可。
{
error: 'Invalid API key'
}
(9)、预期返回结果
当使用不同的HTTP动词向服务器请求时,客户端需要在返回结果里面拿到一系列的信息。下面的列表是非常经典的RESTful API定义:
GET /collection: 返回一系列资源对象
GET /collection/resource: 返回单独的资源对象
POST /collection: 返回新创建的资源对象
PUT /collection/resource: 返回完整的资源对象
PATCH /collection/resource: 返回完整的资源对象
DELETE /collection/resource: 返回一个空文档
(10)、认证 (Authentication)
服务器在大多数情况下是想确切的知道谁创建了什么请求。当然,有些API是提供给公共用户(匿名用户)的,但是大部分时间里也是代表某人的利益。
OAuth2.0提供了一个非常好的方法去做这件事。在每一个请求里,你可以明确知道哪个客户端创建了请求,哪个用户提交了请求,并且提供了一种标准的访问过期机制或允许用户从客户端注销,所有这些都不需要第三方的客户端知道用户的登陆认证信息。
还有OAuth1.0和xAuth同样适用这样的场景。无论你选择哪个方法,请确保它为多种不同语言/平台上的库提供了一些通用的并且设计良好文档,因为你的用户可能会使用这些语言和平台来编写客户端。