RESTful

RESTful

RESTful架构:一种软件的架构风格,设计风格, 为客户端和服务端的交互提供一组设计原则和约束条件。如果一个架构符合REST的约束条件和原则,就称它为RESTful架构。 REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”或“表现层状态转化”。

web服务交互

在浏览器中能看到的每个网站,都是一个web服务。在提供每个web服务的时候, 都需要前后端交互,前后端交互就一定有一些实现方案,通常叫web服务交互方案。

目前主流的三种web服务交互方案:

  • REST ( Representational State Transfer)表征性状态转移【这里所说的表征性,其实指的就是资源。通常称为资源状态转移。】
  • SOAP (Simple Object Access Protocol) 简单的对象访问协议
  • XML-RPC (XML Remote Procedure Call)基于XML的远程过程调用

什么是URI,URL

  • 资源:任何事物,只要有被引用到的必要,它就是一个资源。资源可以是一个实体,也可以是抽象概念。比如在浏览器中看到的文本,视频,图片等等都是实体资源。也可以是抽象的概念,比如两个人的关系......
  • URI(统一资源标志符)是给资源进行标识的,在web中的唯一标识就是URI
  • URL(统一资源定位符)是描述资源地址的。URL可以说是URI的子集,通过定位的方式实现的URI
  • URI类似身份证是唯一的,URL类似家庭住址xx省/xx市/xx村/xx号街道/xx号楼/Alex

统一资源接口

  • 我们可以通过URL去访问到资源,对资源会有很多不同的操作,增删改查
  • 以前可能会为了这个增加新设计一个URL,这个URL就是对数据进行增加的, 还会为了更新和删除分别设计一个URL
  • 现在不用了,只有一个URL,然后根据HTTP请求方式的不同,对资源进行不同的操作,这个就是是统一资源接口
  • 一定要遵循HTTP请求方法的语义,也就是说POST请求就在新增数据等....

资源的表述

  • 资源的表述其实就是资源的展现形式,客户端和服务端传输的都是资源的表述,而不是资源本身
  • 例如文本资源可以采用html、xml、json等格式,图片可以使用PNG或JPG展现出来
  • 那么客户端如何知道服务端提供哪种表述形式呢? 可以通过HTTP内容协商,客户端可以通过Accept头请求一种特定格式的表述,服务端则通过Content-Type告诉客户端资源的表述形式。
  • 这些资源的表述呈现在页面上,就是资源状态。

状态转移

  • 我们在看页面的时候,从当前资源的表述(也可以说状态或者表现层)会跳转到其他的资源状态
  • 服务端通过超媒体告诉客户端当前状态有哪些后续状态可以进入
  • 这些类似"下一页"之类的链接起的就是这种推进状态的作用——指引你如何从当前状态进入下一个可能的状态

REST风格特点

  • (1)在web中,只要有被引用的必要都叫资源。
  • (2)每个URI代表一个资源,独一无二的。
  • (3)客户端通过HTTP的方法,对服务器端资源进行操作;
  • (4)客户端和服务器之间,传递这种资源的某种表现层;
  • (5)通过超链接的指引,实现"表现层状态转移"。

RESTful规范

  1. 路径:面向资源编程
    • 每个URL代表一种资源,URL中尽量不要用动词,要用名词(可复数)。
    • https://api.example.com/v1/zoos
    • https://api.example.com/v1/animals
    • https://api.example.com/v1/employees
  2. method:根据method不同,进行不同的操作
    • GET/POST/PUT/DELETE/PATCH
    • GET :从服务器取出资源(一项或多项)
    • POST :在服务器新建一个资源
    • PUT :在服务器更新资源(客户端提供改变后的完整资源)
    • PATCH :在服务器更新资源(客户端提供改变的属性)
    • DELETE :从服务器删除资源
  3. 版本:在URL中体现版本
    • https://www.bootcss.com/v1/mycss
    • https://v1.bootcss.com/mycss
  4. 域名:在URL中体现是否是API
    • https://www.bootcss.com/api/mycss
    • https://api.bootcss.com/mycss
  5. 过滤:通过在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:指定筛选条件
  6. 协议:尽量使用HTTPS
    • https://www.bootcss.com/v1/mycss
  7. 状态码:
    • 1** 信息,服务器收到请求,需要请求者继续执行操作
    • 2** 成功,操作被成功接收并处理
    • 3** 重定向,需要进一步的操作以完成请求
    • 4** 客户端错误,请求包含语法错误或无法完成请求
    • 5** 服务器错误,服务器在处理请求的过程中发生了错误
    • 更多看这里:http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
  8. 返回值:针对不同操作,服务器向用户返回的结果应该符合以下规范
    • GET请求 返回查到所有或单条数据
    • POST请求 返回新增的数据
    • PUT请求 返回更新数据
    • PATCH请求 局部更新 返回更新整条数据
    • DELETE请求 返回值为空
  9. 错误处理:
    • 状态码是4xx时,应返回错误信息,error当做key。
    • { error: "Invalid API key" }
  10. Hypermedia API: 如果遇到需要跳转的情况 携带调转接口的URL
    • RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。
ret = {
                code: 1000,
                data:{
                    id:1,
                    name:'小强',
                    depart_id:http://www.luffycity.com/api/v1/depart/8/
                },
                link: {
                  "rel":   "collection https://www.example.com/zoos",
                  "href":  "https://api.example.com/zoos",
                  "title": "List of zoos",
                  "type":  "application/vnd.yourformat+json"
                }
            }
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 - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。
502:网关不可用
503:服务不可用   Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
504:网关超市
505:版本不支持

为什么要做前后端分离的项目

  1. 满足多端适配
    • 随着移动端的兴起,现在公司产品不只限于pc端的,包括Android,IOS。
    • 按照以前的方式,后端其实就要有多套,pc一套,APP端两套。
    • 开发成本以及开发效率会很低,如果前后端分离,后端只需要有一套就可以了
    • 后端只提供接口,前端不管是pc还是APP都可以去调用数据。
  2. 前后端职责不清晰
    • 我们的模板语言到底是前端写还是后端写
  3. 开发效率 前后端互相等待
  4. 前端配合后端,只写模板语言,能力受限
  5. 后端开发语言与模板语言耦合度较高,依赖开发语言,更换后端语言的成本加大。

基于Django实现

路由系统:

urlpatterns = [
    url(r'^users/$', views.Users.as_view()),
    url(r'^users2/$', views.user2),

]

视图函数:

import json

def  user2(request):
    if request.method=='GET':
        dic = {'status':200,'name': 'lqz2', 'age': 18}
        return HttpResponse(json.dumps(dic))
    elif request.method=='POST':
        dic = {'status': 200, 'msg': '修改成功'}
        return JsonResponse(dic)

class Users(View):
    def get(self, request):
        dic = {'status':200,'name': 'lqz', 'age': 18}
        return HttpResponse(json.dumps(dic))

    def post(self, request):
        dic = {'status': 200, 'msg': '修改成功'}
        return JsonResponse(dic)
原文地址:https://www.cnblogs.com/bubu99/p/10487188.html