• Restful


     

    什么是RESTful

    一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

    一、URI规范

    1.不用大写;

    2.用中杠 - 不用下杠 _ ;

    3.参数列表要encode;

    4.URI中的名词表示资源集合,使用复数形式。

    5.在RESTful架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词(特殊情况可以使用动词),而且所用的名词往往与数据库的表格名对应。

    资源集合 vs单个资源

    URI表示资源的两种方式:资源集合、单个资源。

    资源集合:

           /zoos //所有动物园

           /zoos/1/animals //id为1的动物园中的所有动物

    单个资源:

           /zoos/1//id为1的动物园

           /zoos/1;2;3//id为1,2,3的动物园

    避免层级过深的URI

    在url中表达层级,用于 按实体关联关系进行对象导航 ,一般根据id导航。

    过深的导航容易导致url膨胀,不易维护,如 GET /zoos/1/areas/3/animals/4 ,尽量使用查询参数代替路径中的实体导航,如 GET/animals?zoo=1&area=3 ;

    二、   版本

    应该将API的版本号放入到URI中

    https://api.example.com/v1/zoos

    三、 Request

    HTTP方法

    通过标准HTTP方法对资源CRUD:

    GET:查询(从服务器取出资源一项或多项)

    GET /zoos

    GET /zoos/1

    GET/zoos/1/employees

     

    POST:创建单个新资源。 POST一般向“资源集合”型uri发起

    POST/animals  //新增动物

    POST/zoos/1/employees //为id为1的动物园雇佣员工

    PUT:更新单个资源(全量),客户端提供完整的更新后的资源。与之对应的是 PATCH,PATCH负责部分更新,客户端提供要更新的那些字段。 PUT/PATCH一般向“单个资源”型uri发起

    PUT/animals/1

    PUT /zoos/1

     

    DELETE:删除

    DELETE/zoos/1/employees/2

    DELETE/zoos/1/employees/2;4;5

    DELETE/zoos/1/animals  //删除id为1的动物园内的所有动物

     

    HEAD / OPTION/ PATCH用的不多,就不多解释了。

    HEAD:获取资源的元数据

    OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的

    PATCH:在服务器更新资源(客户端提供改变的属性)

     

    安全性和幂等性

    1.     安全性 :不会改变资源状态,可以理解为只读的;

    2.     幂等性 :执行1次和执行N次,对资源状态改变的效果是等价的。

    .

    安全性

    幂等性

    GET

    POST

    ×

    ×

    PUT

    ×

    DELETE

    ×

    安全性和幂等性均不保证反复请求能拿到相同的response。以 DELETE为例,第一次DELETE返回200表示删除成功,第二次返回404提示资源不存在,这是允许的。

    复杂查询

    查询可以捎带以下参数:

    .

    示例

    备注

    过滤条件

    ?type=1&age=16

    允许一定的uri冗余,如 /zoos/1 与 /zoos?id=1

    排序

    ?sort=age&order=asc

    指定返回结果按照哪个属性排序,以及排序顺序

    投影

    ?whitelist=id,name,email

    分页

    ? page=2&per_page=100

    指定第几页,以及每页的记录数

    Bookmarker

    经常使用的、复杂的查询标签化,降低维护成本。

    如:GET /trades?status=closed&sort=created,desc

    快捷方式:GET /trades#recently-closed或者GET /trades/recently-closed

     

    状态码

        服务器向用户返回的状态码和提示信息,常见的有以下一些(方括号中是该状态码对应的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 - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。

    状态码的完全列表参见这里

     

    URI失效

    随着系统发展,总有一些API失效或者迁移,对失效的API,返回404 not found 或 410 gone;对迁移的API,返回 301重定向。

     

    四、Response

    1.    不要包装:

    response的 body 直接就是数据,不要做多余的包装。错误示例:

    {

       "success":true,

       "data":{"id":1,"name":"xiaotuan"},

    }

    2.    各HTTP方法成功处理后的数据格式:

    ·

    response 格式

    GET

    单个对象、集合

    POST

    新增成功的对象

    PUT/PATCH

    更新成功的对象

    DELETE

     

    五、错误处理

    1.     不要发生了错误但给2xx响应,客户端可能会缓存成功的http请求;

    2.     正确设置http状态码,不要自定义;

    3.     Response body提供

    即:返回的信息中将error作为键名,出错信息作为键值即可

    1)错误的代码(日志/问题追查);

    2)错误的描述文本(展示给用户)。

     

    对第三点的实现稍微多说一点:

    Java服务器端一般用异常表示 RESTful API的错误。API 可能抛出两类异常:业务异常和非业务异常。 业务异常 由自己的业务代码抛出,表示一个用例的前置条件不满足、业务规则冲突等,比如参数校验不通过、权限校验失败。 非业务类异常 表示不在预期内的问题,通常由类库、框架抛出,或由于自己的代码逻辑错误导致,比如数据库连接失败、空指针异常、除0错误等等。

    业务类异常必须提供2种信息:

    1.     如果抛出该类异常,HTTP响应状态码应该设成什么;

    2.     异常的文本描述;

    在Controller层使用统一的异常拦截器:

    1.     设置 HTTP响应状态码:对业务类异常,用它指定的 HTTPcode;对非业务类异常,统一500;

    2.     Response Body的错误码:异常类名

    3.     Response Body的错误描述:对业务类异常,用它指定的错误文本;对非业务类异常,线上可以统一文案如“服务器端错误,请稍后再试”,开发或测试环境中用异常的 stacktrace,服务器端提供该行为的开关。

    常用的http状态码及使用场景:

    状态码

    使用场景

    400 bad request

    常用在参数校验

    401 unauthorized

    未经验证的用户,常见于未登录。如果经过验证后依然没权限,应该 403(即 authentication和 authorization的区别)。

    403 forbidden

    无权限

    404 not found

    资源不存在

    500 internal server error

    非业务类异常

    503 service unavaliable

    由容器抛出,自己的代码不要抛这个异常

     

    六、其他

    (1)API的身份认证应该使用OAuth2.0框架

    (2)服务器返回的数据格式,应该尽量使用JSON,避免使用XML

    (3)比较复杂的接口不能确定是使用POST还是PUT时,要看具体的业务层代码,看看接口产生的结果是否幂等,如果幂等用PUT,相反用POST

          如:接口接收到一资源,资源存在更新,不存在插入新数据,这个接口就要用PUT

     

    参考:https://blog.csdn.net/u013731455/article/details/56278168

     

    restful 规范
     
           1. 根据method不同,进行不同操作
               GET/POST/PUT/DELETE/PATCH
           2. 面向资源编程
               http://www.nnblog.com/blog
            
           3. 体现版本
               http://www.nnblog.com/v1/blog
               http://www.nnblog.com/v2/blog
                
               https://v4.bootcss.com/
               https://v3.bootcss.com/
           4. 体现是API
               http://www.nnblog.com/api/v1/blog
               http://www.nnblog.com/api/v2/blog  
                
               http://api.nnblog.com/v1/salary
               http://api.luffycity.com/v2/blog   
           5. https
               https://www.nnblog.com/api/v1/blog
               https://www.nnblog.com/api/v2/blog 
                
           6. 响应式设置状态码
               200
               300
               400
               500
               return HttpResponse('adfasdf',status=300)
            
           7. 条件
               https://www.nnblog.com/api/v2/blog?page=1&size=10
            
           8. 返回值
               https://www.nnblog.com/api/v2/salary
               GET: 所有列表
               {
                   code: 10000,
                   data: [   
                       {'id':1,'title':'a'},
                       {'id':1,'title':'b'},
                       {'id':1,'title':'c'},
                   ]
               }
                    
               POST: 返回新增的数据
                   {'id':1,'title':'高亮'}
                    
               https://www.nnblog.com/api/v2/salary/1/
               GET: 获取单条数据
                       {'id':1,'title':'d'}
               PUT:更新
                       {'id':1,'title':'e'}
               PATCH: 局部更新
                       {'id':1,'title':'f'}
               DELETE:删除
                    
           9. 返回错误信息
               {
                   code: 100001,
                   error: 'xxx错误'
               }
            
           10. Hypermedia API
               ret = {
                   code: 1000,
                   data:{
                       id:1,
                       name:'付勇',
                       depart_id:http://www.nnblog.com/api/v1/blog/8/
                   }
               }

    最后的一个总结:

     restful 规范(10个)

    什么是接口?

    - URL

    - 约束
    # 约束继承(实现)了他的类中必须含有IFoo中的方法(Java中)

    #interface IFoo:
    #    def func(self): pass 
    
    #class Foo(IFoo):
    #    def func(self): 
    #    print(11111)
    View Code

    1. 根据method不同,进行不同操作

    GET/POST/PUT/DELETE/PATCH

    2. 面向资源编程

    http://www.luffycity.com/salary(后缀尽量使用名词,比如工资)

    3. 体现版本

    http://www.luffycity.com/v1/salary(加上版本号)
    http://www.luffycity.com/v2/salary

    https://v4.bootcss.com/ bootstrap3
    https://v3.bootcss.com/ bootstrap4

    4. 体现是API

    http://www.luffycity.com/api/v1/salary (加上api表示api接口而不是网站)
    http://www.luffycity.com/api/v2/salary

    http://api.luffycity.com/v1/salary (这个也可以,但是推荐上面的,这个会出现跨域问题)
    http://api.luffycity.com/v2/salary

    5. https(安全建议使用https,需要证书)

    https://www.luffycity.com/api/v1/salary
    https://www.luffycity.com/api/v2/salary

    6. 响应式设置状态码

    200 成功
    300 重定向(301(永久重定向),302(临时重定向))
    400 失败(404)
    500 服务器有错(代码写错了)

    return HttpResponse('xxxxxxxx',status=300)

    7. 条件

    【加特定条件以及分页】[比如一千万条数据肯定不能都返回]

    https://www.luffycity.com/api/v2/salary?page=1&size=10

    8. 返回值

    1.这个请求只有get和post

    https://www.luffycity.com/api/v2/salary
    GET: 所有列表

    {
    code: 10000,
    data: [ 
    {'id':1,'title':'高亮'},
    {'id':1,'title':'龙泰'},
    {'id':1,'title':'小东北'},
    ]
    }

    POST: 返回新增的数据

    {'id':1,'title':'高亮'}

    2.这个请求根据单挑数据可以增删改查

    https://www.luffycity.com/api/v2/salary/1/
    GET: 获取单条数据

    {'id':1,'title':'高亮'}

    PUT:更新

    {'id':1,'title':'高亮'}

    PATCH: 局部更新

    {'id':1,'title':'高亮'}

    DELETE:删除
    返回一个空文档

    9. 返回错误信息(是一个字典)

    err={code: 10001,error: 'xxx错误'}

    以后使用code

    10. Hypermedia API(一般不使用)

    ret = {
    code: 1000,
    data:{
    id:1,
    name:'小强',
    depart_id:http://www.luffycity.com/api/v1/depart/8/
    }
    }


    建议使用restful规范

    根据公司项目需求来进行使用这些规范,而不是强行使用。 
     
     

    django rest framework框架(回顾)

    - 权限
    - 认证
    - 访问频率限制
    - 序列化
    - 路由
    - 视图

    面试题:你的写的类都继承过哪些类?

    class View(object):
    class APIView(View):
    class GenericAPIView(views.APIView):
    class GenericViewSet(ViewSetMixin, generics.GenericAPIView)
    class ModelViewSet(mixins.CreateModelMixin,mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin,mixins.ListModelMixin,GenericViewSet):
    class AuthorModelView(viewsets.ModelViewSet):

    - 分页
    - 解析器
    - 渲染器
    - 版本

    最后额外补充复习:

    django请求生命周期

    -> 1.执行遵循wsgi协议的模块(socket服务端)
    -> 2.中间件(路由匹配)
    -> 3.视图函数(业务处理:ORM、模板渲染)
    -> 4.中间件
    -> 5.wsgi返回

    2. 什么是wsgi

    web服务网关接口
    实现该协议的模块:
    - wsgiref(测试版本,性能差)
    - werkzurg
    - uwsig(线上使用的)

    Django组件

    (认证组件,csrftoken,form组件,modelform,session组件,admin组件,分页器)

    3. 视图

    - FBV
    url - 函数
    - CBV
    url - 类名.as_view()加括号执行-->view(返回view)-->view里面触发dispatch进行分发。

  • 相关阅读:
    Spark学习(一)Spark初识
    service mysqld restart mysqld: 未被识别的服务
    Spark学习(二)Spark 版本 WordCount
    java.sql.SQLException: Incorrect string value: '\xE4\xB8\xAD\xE9\x83\xA8' for column 'area' at row 1
    centos 6.8 yum源不可用安装报YumRepo Error: All mirror URLs are not using ftp, http[s] or file
    互联网运维装腔指南
    PHP生成一段时间之间的月份列表
    sql根据分组后排序取第一条数据
    sql 多行拼接 成一行
    js 常用汇总
  • 原文地址:https://www.cnblogs.com/geogre123/p/9744834.html
Copyright © 2020-2023  润新知