文章目录
-
- REST 对请求的约定
-
- 什么是RESTful?
- 一、最原始的接口开发
- 二、优化接口开发(FBV)
- 三、进一步优化,基于CBV模式来开发(CBV)
- 四、RESTful规范
- RESTful API设计
-
- HTTPs规范。
- 域名规范:
- 版本规范。
- 路径规范。
- method规范。
- 过滤规范。
- 状态码规范
- 错误处理规范
- 返回数据规范
- Hypermedia API 规范 :
- 谈谈自己对 restful api 规范的认识 ?
REST 对请求的约定
要解释什么是REST,你应该先了解什么是API(Application Programming Interface,应用程序编程接口)
形象一点说就是像一个公司比如腾讯,阿里巴巴之类,他们可以提供一个API,然后我们或者一些其他的小公司可以编一个软件去跟这个接口(API)进行相连或交互。
举个例子,比如你可以用手机的其他软件分享内容到微信朋友圈或者新浪微博,这些软件就是与微信和微博的api进行了交互。
REST 用来规范应用如何在 HTTP 层与 API 提供方进行数据交互 ?
REST 描述了 HTTP 层里客户端和服务器端的数据交互规则;客户端通过向服务器端发送 HTTP(s)请求,接收服务器的响应,完成一次 HTTP 交互。
这个交互过程中,REST 架构约定两个重要方面就是 HTTP 请求的所采用方法,以及请求的链接。
在请求层面,REST 规范可以简单粗暴抽象成以下两个规则:
1 2 | * 请求 API 的 URL 表示用来定位资源; * 请求的 method 表示对这个资源进行的操作; |
什么是RESTful?
- REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”
- REST从资源的角度类审视整个网络,它将分布在网络中某个节点的资源通过URL进行标识,客户端应用通过URL来获取资源的表征,获得这些表征致使这些应用转变状态
- REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”
- 所有的数据,不过是通过网络获取的还是操作(增删改查)的数据,都是资源,将一切数据视为资源是REST区别与其他架构风格的最本质属性
- 对于REST这种面向资源的架构风格,有人提出一种全新的结构理念,即:面向资源架构(ROA:Resource Oriented Architecture)
一、最原始的接口开发
这种方式虽然可以实现接口的开发,但是一个表的处理就需要4个url,当表单多的时候,需要写大量的url,这样不利于开发,并不是接口开发的最好方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # url路由分配 urlpatterns = [ path('get_order/', views.get_order), path('add_order/', views.add_order), path('del_order/', views.del_order), path('update_order/', views.update_order) ] # 视图函数处理 def get_order(request): return HttpResponse(' ') def add_order(request): return HttpResponse(' ') def del_order(request): return HttpResponse(' ') def update_order(request): return HttpResponse(' ') |
二、优化接口开发(FBV)
根据request中method的不同,来执行对应的方法,返回值给前端,这一种开发优化了上一种开发方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # 把原来的四条合并为一条 urlpatterbs = [ path('order/', views.order), ] # 视图函数中通过判断request方法来进行对应的处理 def order(request): if request.method == 'GET': return HttpResponse("获取一条或者多条订单") elif request.method == 'POST': return HttpResponse("增加一条订单") elif request.method == 'PUT': return HttpResponse("更新一条订单") elif request.method == 'DELETE': return HttpResponse("删除一条订单") |
三、进一步优化,基于CBV模式来开发(CBV)
在FBV基础上进一步优化,CBV开发模式下继承了FBV中的路由简化,同时也改进了视图函数,开发人员不需要再对request方法进行判断,直接可以开发。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #url中的路由分配, 使用 CBV 模式的时候由于需要调用 dispatch方法,必须在url中的视图后添加 as_view()方法 urlpatterns = [ path('order1/', views.Order.as_view()), ] # 基于CBV模式进行接口的开发 from django.views import View from django.utils.decorators import method_decorator @method_decorator(csrf_exempt, name='dispatch') class Order(View): def get(self, request, *args, **kwargs): return HttpResponse("获取一条或者多条订单") def post(self, request, *args, **kwargs): return HttpResponse("增加一条订单") def put(self, request, *args, **kwargs): return HttpResponse("更新一条订单") def delete(self, request, *args, **kwargs): return HttpResponse("删除一条订单") |
四、RESTful规范
RESTful规范是一种网络架构风格,它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。但是是否遵循该规范以及如何遵循该规范需要根据具体的业务需求来决定。深入理解RESTful规范
RESTful API设计
HTTPs规范。
API与用户通信协议,总是使用 HTTPs协议。,这个协议比HTTP更加安全, 确保交互数据的传输安全
域名规范:
方式一: 把www.换成api. 例如:正常的子域名是https://www.baidu.com,如果使用api接口,可以把子域名设置成https://api.baidu.com进行区分。但是需要注意的是,这种方式需要开发者自己来解决跨域请求的问题。
方式二:同一个域名,在url设置上进行区分,在域名后添加api,例如:正常的url是https://www.baidu.com,API接口的url可以设置成https://www.baidu.com/api/,这种设置由于域名是同一个域名,不存在跨域请求的问题,使用更加的方便。
版本规范。
1 2 3 4 5 6 7 8 | - 在 Restful API 中,API应当尽量兼容之前的版本。Web端很容易为了适配服务端的新的 API 接口进行版本升级,而 Android 、IOS等客户端必须通过用户主动升级产品到新版本,才能适配新接。 - 为了解决这个问题,在设计 Restful API时一般情况下会在 URL 中半流版本号,并同时兼容多个版本: - 程序的开发过程中会不断的升级,每一次升级都是一个版本,所以开发者需要给程序添加版本用于区分。添加的方式有两种: - 方式一:把版本号添加到url后,例如设置 https://www.baidu.com/api/v1/,v1既是开发的版本号。 - 方式二:把版本好添加到请求头上 |
一般情况下使用的是第一种方式
路径规范。
面向资源编程:REST 是面向资源的, 把网络上的任何内容都看作是资源,对资源进行增、删、改、查操作。基于面向资源,API接口url设置上尽量使用名词来设置,可以写复数形式。例如:设置https://www.baidu.com/api/v1/source/,注意:source为名词,如果设置成get_source则是动词形式的。
1 2 3 4 5 | 比如:左边是不规范的设计,而右边是正确的 GET /rest/api/getDogs --> GET /rest/api/dogs 获取所有小狗狗 GET /rest/api/addDogs --> POST /rest/api/dogs 添加一个小狗狗 GET /rest/api/editDogs/:dog_id --> PUT /rest/api/dogs/:dog_id 修改一个小狗狗 GET /rest/api/deleteDogs/:dog_id --> DELETE /rest/api/dogs/:dog_id 删除一个小狗狗 |
method规范。
GET : 从服务器上获取一项或多项资源
POST : 在服务器上新建一个资源
DELETE : 从服务器上删除资源
PUT : 在服务器上更新资源(客户端提供改变后的完整资源)
PATCH : 在服务器上更新资源(客户端提供改变的属性)
过滤规范。
通过在url上传参的形式传递搜索条件,例如:设置https://www.baidu.com/api/v1/source/?name=李明&age=23
查询参数
REST 风格的接口地址,表示的可能是单个资源,也可能是资源的集合;当我们需要访问资源集合时,设计良好的接口应当接受参数,允许只返回满足某些特定条件的资源列表。
公共参数
常规的公共查询参数有:
参数名 作用
offset 返回记录的开始位置
limit 返回记录的数量
keyword 提供关键词进行搜索
sort 指定排序的字段
orderby 指定排序方式
具体来看:
(1)以offset和limit参数来进行分页:
1 | GET /api/users?offset=0&limit=20 |
(2)使用keyword提供关键词进行搜索:
1 | GET /api/users?keyword=john |
(3)使用sort参数和orderby参数进行排序
1 2 | GET /api/users?sort=age&orderby=asc // 按年龄升序 GET /api/users?sort=age&orderby=desc // 按年龄降序 |
有的时候也可以只用orderby来进行排序:
1 2 | GET /api/users?se&orderby=age_asc // 按年龄升序 GET /api/users?se&orderby=age_desc // 按年龄降序 |
状态码规范
服务器向用户返回的状态码和提示信息,常见的有以下一些(方括号中是该状态码对应的HTTP动词)。
1 2 3 4 5 6 7 8 9 10 11 12 | 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 - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。 |
更多看这里:http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
在实际的项目开发中,可能会出现很多的情况,虽然现有的status_code已经有很多,但并不能包括所有的情况,所以,需要把 status_code 与code 相结合来使用,code由开发者自己定义值和所代表的情况,当然status_code和code都可单独使用。
错误处理规范
当 RESTful API 接口出现非 4xx 的HTTP 错误码响应时,采用全局的异常结构响应信息。
一般来说,返回的信息中将error作为键名,出错信息作为键值即可。
1 2 3 | {<!-- --> error: "Invalid API key" } |
返回数据规范
GET/collection: 返回资源对象的列表(数组)
GET/collection/resource: 返回单个资源对西那个
POST/collection: 返回新生成的资源对象
PUT/collection/resource: 返回更新后的完整的资源对象
PATCH/collection/resource: 返回更新后的完整资源对象
DELETE/collection/resource: 删除后返回一个空文档
resource一般指的是数据中的pk值
接口返回模板:
1 2 3 4 5 | {<!-- --> status:0, data:{<!-- -->}||[], msg:’’ } |
Hypermedia API 规范 :
RESTful API最好做到Hypermedia,即:返回的结果中提供链接,连向其他API的方法,使得用户不查文档也知道下一步做什么。
例如:在返回结果中提供相关资源的链接,连向其他API方法
1 2 3 4 5 6 7 8 9 | {<!-- --> "link": {<!-- --> "rel": "collection https://www.example.com/zoos", "href": "https://api.example.com/zoos", "title": "List of zoos", "type": "application/vnd.yourformat+json" } } |
谈谈自己对 restful api 规范的认识 ?
其实本质上还是一个规范,定义一些规范可以让我们写 api 时,更好的让我们区分,更容易让前端记住那些URL,目标让那些URL更能体现出对api 的操作。
在我没写 restful 之前,执行一些函数,如: get, post, delete,update, 都要保存好多个URL,虽然还是会实现这些URL所对应的功能,但通过规范可以让团队协同开发时相互之间都遵循一个规范(约定),这样开发就比较统一了。
最显著的特点:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | # 用Restful: 给用户一个url,再根据不同的method在后端做不同的处理 比如:post创建数据、get获取数据、put和patch修改数据、delete删除数据。 # 不用Restful: 给调用者很多url,每个url代表一个功能,比如:add_user/delte_user/edit_user/ # 当然,还有其他的,比如: '版本' 来控制让程序有多个版本共存的情况,版本可以放在 url、请求头(accept/自定义)、GET参数 '状态码' 200/300/400/500 'url中尽量使用名词' restful也可以称为“面向资源编程” 'api标示' api.luffycity.com www.luffycity.com/api/ |