美文网首页
开发规范

开发规范

作者: lkning | 来源:发表于2018-03-02 10:27 被阅读0次

    Web后端规范

    不久将来,整个行业存在的唯一目的就是消费平台上的数据。你的API越容易使用,那么就 会有越多的人去用它。立足现在,展望未来,restful风格的api是我们必然的趋势。

    定义

    • 资源: 一个对象的实例
    • 集合:一群同种对象
    • HTTP:跨网络的通信协议
    • 客户端:可以创建HTTP请求的客户端应用程序
    • 第三方开发者:这个开发者不属于你的项目但是有想使用你的数据
    • 服务器:一个HTTP服务器或者应用程序,客户端可以跨网络访问它
    • 端点:这个API在服务器上的URL用于表达一个资源或者一个集合
    • 幂等:无边际效应,多次操作得到相同的结果
    • URL段:在URL里面已斜杠分隔的内容

    URL

    URI 表示资源,资源一般对应服务器端领域模型中的实体类。

    URL规范

    1. 不用大写字符
    2. 只用下划线_连接
    3. 名词表示资源的集合,使用复数

    资源集合,单个资源

    资源集合

    /zooms/  # 所有动物园
    /zooms/1/employees/  # id为1的动物园的所有职工
    

    单个资源

    /zooms/1/  # id为1的动物园
    

    避免层级过深的url

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

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

    Request

    动词

    五个非常重要的HTTP动词必须知道

    • GET (选择):从服务器上获取一个具体的资源或者一个资源列表,具备幂等性
    • POST (创建): 在服务器上创建一个新的资源, 不具备幂等性
    • PUT (更新):以整体的方式更新服务器上的一个资源, 具备幂等性
    • PATCH (部分更新):只更新服务器上一个资源的部分属性, 具备幂等性
    • DELETE (删除):删除服务器上的一个资源, 具备幂等性

    原则上,只允许客户端或者第三方调用者使用这五个HTTP动词进行数据交互,并且在URL段 里面不出现任何其他的动词。有写操作的动词性很强, 不太容易用一个名词来表述,可以 逻辑上换一个方式来处理,比如作废一张订单,可以采用两种方式来实现。一是修改订单的 状态和相关字段(PATCH方法,这种的业务逻辑性不强,不清晰,不推荐),另一种是把作废 的订单看作一种逻辑资源,只需要在这种资源集合中使用POST方法创建一个资源即可。

    另外一般情况下,GET请求要考虑缓存(客户端,服务器都要考虑),减少服务器检索数据的 压力。

    版本化

    API是服务器与客户端之间的一个公共契约。对服务器上的API做了一个更改,并且这些更改 无法向后兼容,那么就打破了这个契约。这时候既要确保应用程序逐步的演变,又要让客户 端继续可用。那么必须在引入新版本API的同时保持旧版本API仍然可用。所以接口必须版本 化

    1. 如果只是简单的增加一个新的特性到API上,如资源上的一个新属性或者增加一个新的端 点,不需要增加API的版本。因为这些并不会造成向后兼容性的问题,只需要修改文档即可。
    2. 申明不支持一个特性并不意味着关闭或者破坏它。而是告诉客户端旧版本的API将在某个 特定的时间被删除,并且建议他们使用新版本的API。
    3. 在URL中包含版本信息 GET /v1/zooms/ GET /v2/zooms/1/animals/

    UserAgent

    所有请求的Header信息中必须按照格式填写User-Agent信息,格式:

    type|os|os_version|product|version|...
    

    说明:

    • type: 客户端类型, [MOBILE, DESKTOP, BROWSER]
    • os: 操作系统, [Android, iOS, Chrome, IE ...]
    • os_version: 操作系统版本号, 包含完整信息,比如:Windows 7 Ultimate Service Pack 1 64bit
    • product: 产品, [KLICEN_APP, ZEUS(宙斯系统),ZEUS_APP(宙斯系统App), KLICEN_EP(凯励程企业版) ,INSTALL(安装工具), VUS(欣悦途), EWS(预警系统)]
    • version: 客户端版本号

    手机端必须增加 手机品牌|手机型号|屏幕分辨率 没有的用空表示;必须包含前面五个字段。例如:

    "User-Agent": "MOBILE|Android|7.0|KLICEN_APP|2.2.5|Dalvik/2.1.0 (Linux; U; Android 7.0; FRD-AL00 Build/HUAWEIFRD-AL00)|1080*1794|863549034263964"
    

    Response

    内容类型

    接口只提供两种类型的返回内容

    • 全部接口默认支持json
    • 部分接口支持excel表格/csv,数据导出作为一种返回格式,导出权限可配置 /animals/?zoom=1&format=excel # 导出id为1的动物园的所有动物数据 ### 预期返回的内容
    • GET /collection/?page=1&page_size=15: 返回一系列资源对象,分页
    • GET /collection/resource/: 返回单独的资源对象
    • POST /collection/: 返回新创建的资源对象
    • PUT /collection/resource/: 返回完整的资源对象
    • PATCH /collection/resource/: 返回完整的资源对象
    • DELETE /collection/resource/: 返回一个空文档

    使用ISO8601的国际化时间格式

    接收和返回时间数据时只使用UTC格式

    "create_at": "2012-01-01T12:00:00Z"
    

    枚举型

    枚举类型的字段返回其名值对:

    {
        "key": 存储值,
        "verbose": 显示值
    }
    
    

    提供标准的时间戳

    提供默认的资源创建时间,更新时间 created_at and updated_at, 例如:

    {
      ...
      "created_at": "2012-01-01T12:00:00Z",
      "updated_at": "2012-01-01T13:00:00Z",
      ...
    }
    

    这些时间戳可能不适用于某些资源,这种情况下可以忽略省去。

    包装

    response 的 body 统一做如下包装。示例:

    {
        "code": 0,
        "msg": "请求成功"(用户友好),
        "data": {
            "id": 1,
            "name": "张三"
        }
    }
    

    使用djangorestframework的情况下,可以在配置文件中配置REST_FRAMEWORK中的DEFAULT_RENDERER_CLASSESutils.renders.CustomJsonRender, 它的具体实现如下:

    # -*- coding: utf-8 -*-
    from rest_framework.renderers import JSONRenderer
    
    class CustomJsonRender(JSONRenderer):
        """ 自定义返回数据 Json格式
        {
            "code": 0,
            "msg": "success",
            "data": { ... }
        }
        """
    
        def render(self, data, accepted_media_type=None, renderer_context=None):
            if renderer_context:
                response = renderer_context['response']
                code = 0 if int(response.status_code / 100) == 2 else response.status_code
                msg = 'success'
                if isinstance(data, dict):
                    msg = data.pop('msg', msg)
                    code = data.pop('code', code)
                    data = data.pop('data', data)
                if code != 0 and data:
                    msg = data.pop('detail', 'failed')
                response.status_code = 200
                res = {
                    'code': code,
                    'msg': msg,
                    'data': data,
                }
                return super().render(res, accepted_media_type, renderer_context)
            else:
                return super().render(data, accepted_media_type, renderer_context)
    
    

    可能的错误信息的code可根据实际情况扩展, 所以要让客户端能获取到这些code

    code码

    • 0 OK - [GET]: 客户端向服务器请求获取数据成功
    • 201 CREATED - [POST/PUT/PATCH]: 客户端向服务器请求改变数据成功
    • 204 NO CONTENT - [DELETE]: 客户端要求服务器删除一个资源,服务器删除成功
    • 400 BAD REQUEST - [POST/PUT/PATCH]: 客户端向服务器提供了不正确的数据,服务器什么也不做
    • 401 UNAUTHORIZED - [*]: 用户未认证
    • 403 FORBIDDEN - [*]: 已认证但权限不够
    • 404 NOT FOUND - [*]: 客户端引用了一个不存在的资源或集合
    • 500 INTERNAL SERVER ERROR - [*]: 服务器发生内部错误,客户端无法得知结果,请求可能已经处理成功

    嵌套外键关系

    序列化的外键关系建立在一个有嵌套关系的对象之上, 例如:

    {
      "name": "成都动物园",
      "manager": {
        "id": 1
      },
      ...
    }
    

    而不是这样, 例如:

    {
      "name": "成都动物园",
      "owner_id": 1,
      ...
    }
    

    这种方式把相关联的资源信息内联在一起,在返回更多信息时不用改变响应资源的结构, 例如:

    {
      "name": "成都动物园",
      "owner": {
        "id": 1,
        "name": "张三",
        "email": "zhangsan@klicen.com"
      },
      ...
    }
    

    文档

    • 避免使用文档自动化生成器,即便用了,你也要保证自己审阅过并让它具有更好的版式。
    • 不要截断示例中请求与响应的内容,展示完整的东西。并在文档中使用高亮语法。
    • API的验证授权,包含获取及使用验证tokens
    • API稳定性及版本控制, 包含如何选择所需要的版本
    • 正确的响应和错误的响应都应该文档化,并说明在什么情况下会产生这些的错误

    如果时间允许,甚至可以创建一个控制台来让开发者可以立即体验一下API的功能。

    API分析

    API分析就是持续跟踪那些正为人使用的API的版本和端点信息,这样做的好处是:

    1. 决定什么时候不再支持某个版本
    2. 找到那些使用最广泛的API,用其作为指导业务方向或者优化效率的重要的依据
    3. 更多...

    认证与安全

    认证

    采用OAuth2.0,OAuth2.0提供了一个非常好的方法去做这件事。在每一个请求里, 你可以明确知道哪个客户端创建了请求,哪个用户提交了请求,并且提供了一种标准的访问 过期机制或允许用户从客户端注销,所有这些都不需要第三方的客户端知道用户的登陆认证 信息。

    安全

    这个暂时不是当前的重点,这里只列出几个方向,后期再完善

    • 采用https
    • 访问频次的控制
    • api访问记录的跟踪分析

    相关文章

      网友评论

          本文标题:开发规范

          本文链接:https://www.haomeiwen.com/subject/bogoxftx.html