RESTful规范
一、什么是RESTful(Representational State Transfer)
Representational State Transfer 简称rest,直译文为表征状态转移
如果一个架构符合REST原则,就称它为RESTful架构,与技术无关,代表的是一种软件架构风格
所有的数据,不过是通过网络获取的还是操作(增删改查)的数据,都是资源,将一切数据视为资源是REST区别与其他架构风格的最本质属性
对于REST这种面向资源的架构风格,有人提出一种全新的结构理念,即:面向资源架构(ROA:Resource Oriented Architecture)二、RESTful API设计规范
1. https协议
建议使用https协议替代http协议,让接口数据更加安全。
如果是基于HTTPS协议,则意味着用户浏览器再向服务器发送数据时,都是以密文的形式传输,中途即使有非法用户获取到网络数据,也可以密文的,无法破译。
HTTPS保证了数据安全,但由数据传输存在着加密和解密的过程,所以会比HTTP协议慢一些。
2. 域名
对于后端API接口中要体现API标识,例如:
- https://api.example.com
- https://www.example.com/api/3. 版本(version)
对于后端API接口中要体现版本信息,例如:
- http://api.example.com/v1/
- http://api.example.com/?version=v1
- http://v1.example.com/
- http://api.example.com/
请求头:Accept: application/json; version=v14. 路径(endpoint)
restful API这种风格中认为网络上的一切都称为资源,围绕着资源可以进行增删查改等操作。
举例来说,有一个API提供动物园(zoo)的信息,还包括各种动物和雇员的信息,则它的路径应该设计成下面这样。
https://api.example.com/v1/zoos
https://api.example.com/v1/animals
https://api.example.com/v1/employees5. 请求方法与返回数据
根据请求方法不同进行不同的操作,服务器向用户返回的结果结构也应该不同。
常见请求方法:
GET(SELECT):从服务器取出资源(一项或多项)。
POST(CREATE):在服务器新建一个资源。
PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
DELETE(DELETE):从服务器删除资源。返回示例:
GET /zoos:列出所有动物园
POST /zoos:新建一个动物园
GET /zoos/ID:获取某个指定动物园的信息
PUT /zoos/ID:更新某个指定动物园的信息(提供该动物园的全部信息)
PATCH /zoos/ID:更新某个指定动物园的信息(提供该动物园的部分信息)
DELETE /zoos/ID:删除某个动物园
GET /zoos/ID/animals:列出某个指定动物园的所有动物
DELETE /zoos/ID/animals/ID:删除某个指定动物园的指定动物6. 搜索条件
在URL中通过参数的形式来传递搜索条件,例如:
https://api.example.com/v1/zoos?limit=10 指定返回记录的数量
https://api.example.com/v1/zoos?offset=10 指定返回记录的开始位置
https://api.example.com/v1/zoos?page=2&per_page=100 指定第几页,以及每页的记录数
https://api.example.com/v1/zoos?sortby=name&order=asc 指定返回结果按照哪个属性排序,以及排序顺序
https://api.example.com/v1/zoos?animal_type_id=1 指定筛选条件7. 状态码
后端API在对请求进行响应时,除了返回数据以外,还可以返回状态码,来表示请求状况。
常见状态码:
100(临时响应)表示临时响应并需要请求这继续执行操作的状态码
100-继续请求者应当继续提出请求。服务器返回此代码表示已收到请求的一部分,正在等待其余部分。
101-切换协议 请求者已要求服务器切换协议,服务器已确认并准备切换。200(成功)表示成功处理了请求的状态码
200-成功 服务器已经成功处理了请求。通常,这表示服务器提供了请求的网页。
201-已创建 请求成功并且服务器创建了新的资源。
202-已接受 服务器已接受请求,但尚未处理。
203-非授权信息 服务器已经成功处理了请求,但返回的信息可能来自别的资源。
204-无内容 服务器成功处理了请求,但没有返回任何内容。
205-重置内容 服务器成功处理了请求,但没有返回任何内容。
206-部分内容 服务器成功处理 了部分GET请求。300(重定向)表示要完成请求,需要进一步操作。通常,这些状态代码用来重定向
300-多种选择 针对请求,服务器可执行多种操作。服务器可根据请求者(user agent)选择一项操作,或提供操作列表提供请求者选择。
301-永久移动 请求的网页已永久移动到新位置。服务器回返此响应(对GET或HEAD请求的响应)时,会自动将请求者转到新位置
302- 临时移动 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
303-查看其它位置 请求者应当对不同的位置使用单独的GET请求来检索响应时,服务器返回此代码。
304-未修改 自上次请求后,请求的网页未修改过。服务器返回此响应,不会返回网页的内容。
305-使用代理 请求者只能使用代理访问请求的网页。如果服务器返回此响应,还表示请求者应使用代理。
307-临时性重定向 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有的位置来进行以后的请求。400(请求错误)这些状态码表示可能出错,妨碍了服务器的处理
400-错误请求 服务器不理解请求的语法。
401-未授权 请求要求身份验证。对于需要登陆的网页,服务器可能返回此响应。
403-禁止 服务器拒绝请求。
404-未找到 服务器到不到请求的网页。
405-方法禁用 禁用请求中指定的方法。
406-不接受 无法使用请求的内容特性响应请求的网页。
407-需要代理授权 此状态码与401(未授权)类似,但指定请求者应当授权使用代理。
408-请求超时 服务器等候请求时发生超时。
409-冲突 服务器在完成请求时发生冲突。服务器必须在响应中包含有关冲突的信息。
410- 已删除 如果请求的资源已永久删除,服务器就会返回此响应。
411-需要有效长度 服务器不接受不含有效内容长度标头字段的请求。
412-未满足前提条件 服务器未满足请求者在请求者设置的其中一个前提条件。
413-请求实体过大 服务器无法处理请求,因为请求实体过大,超出了服务器的处理能力。
414-请求的URI过长 请求的URI(通常为网址)过长,服务器无法处理。
415- 不支持媒体类型 请求的格式不受请求页面的支持。
416-请求范围不符合要求 如果页面无法提供请求的范围,则服务器会返回此状态码。
417-未满足期望值 服务器未满足“期望”请求标头字段的要求500(服务器错误)这些状态码表示服务器在尝试处理请求时发生内部错误。这些错误可能是服务器本身的错误,而不是请求出错
500-服务器内部错误 服务器遇到错误,无法完成请求。
501 - 尚未实施 服务器不具备完成请求的功能。例如,服务器无法识别请求方法时可能会返回此代码。
502 - 错误网关 服务器作为网关或代理,从上游服务器无法收到无效响应。
503 - 服务器不可用 服务器目前无法使用(由于超载或者停机维护)。通常,这只是暂时状态。
504 - 网关超时 服务器作为网关代理,但是没有及时从上游服务器收到请求。
505 - HTTP版本不受支持 服务器不支持请求中所用的HTTP协议版本。更多看这里:http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
8. 错误处理
如果状态码是4xx,就应该向用户返回出错信息。一般来说,返回的信息中将error作为键名,出错信息作为键值即可。
{
error: "Invalid API key"
}9. 返回结果
针对不同操作,服务器向用户返回的结果应该符合以下规范。
GET /collection:返回资源对象的列表(数组)
GET /collection/resource:返回单个资源对象
POST /collection:返回新生成的资源对象
PUT /collection/resource:返回完整的资源对象
PATCH /collection/resource:返回完整的资源对象
DELETE /collection/resource:返回一个空文档10. Hypermedia API
RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。
{"link": {
"rel": "collection https://www.example.com/zoos",
"href": "https://api.example.com/zoos",
"title": "List of zoos",
"type": "application/vnd.yourformat+json"
}}三、基于Django的的实现
基于django + restful规范来开发一个后台接口示例。
# urls.py
from django.urls import path
from app01 import views
# http://www.xxx.com/api/v1/users/
urlpatterns = [
path('api/<str:version>/users/', views.users),
path('api/<str:version>/users/<int:pk>/', views.users),
]# views.py
from django.http import JsonResponse
def users(request, version, pk=None):
print("版本:", version)
if not pk:
if request.method == "GET":
# 请求用户列表
info = {
"code": 0,
"data": [{"id": 1, "name": "武沛齐"}]
}
return JsonResponse(info)
elif request.method == "POST":
# 新增用户,读取 request.POST 中提交的数据并添加到数据库中
info = {
"code": 0,
"data": {"id": 1, "name": "武沛齐"}
}
return JsonResponse(info)
else:
info = {
"code": 1000,
"error": "请求错误"
}
return JsonResponse(info)
if request.method == "GET":
# 获取ID=pk的用户信息,并返回
info = {
"code": 0,
"data": {"id": 1, "name": "武沛齐"}
}
return JsonResponse(info)
elif request.method == "DELETE":
# 删除id=pk的用户
info = {
"code": 0,
"data": {}
}
return JsonResponse(info)
elif request.method == "PUT":
# 读取request.POST中的数据 + pk,更新数据库中的用户信息
info = {
"code": 0,
"data": {"id": 1, "name": "武沛齐"}
}
return JsonResponse(info)
elif request.method == "PATCH":
# 读取request.POST中的数据 + pk,更新数据库中的用户信息
info = {
"code": 0,
"data": {"id": 1, "name": "武沛齐"}
}
return JsonResponse(info)
else:
info = {
"code": 1000,
"error": "请求错误"
}
return JsonResponse(info)

浙公网安备 33010602011771号