美文网首页
RESTful API的一个优化变种实现

RESTful API的一个优化变种实现

作者: microkof | 来源:发表于2020-05-08 18:01 被阅读0次

    路径和方法

    1. 所有在前端形成列表的资源,一般都会提供5种操作:列表、单条、增、删、改。尤其不能省掉“单条”,原因是列表中的数据只是基本数据,如果返回全部数据,继而省略掉单条,是不负责任的错误做法,会增加数据库查询负担,并且增加传输流量。

    2. 资源英文单词用单数形式。虽然RESTful API要求用名词复数,但是这样往往由于程序员粗心造成混乱,而且RESTful是美国人提出的,他们对于英文单复数敏感,而中国人并不敏感,所以,本规范要求一律用名词单数。

    3. 路径中要体现出大小类关系,大类写在前,小类写在后。

    举例:

    xxxyyyzzz指代类名。
    ooo指代资源名。

    操作 路径 方法
    无参列表 /xxx/ooo GET
    有参列表 /xxx/ooo?del=1 GET
    单条 /xxx/ooo?id=123 GET
    /xxx/ooo POST
    /xxx/ooo PUT
    /xxx/ooo DELETE

    更复杂的,有大类名还有小类名(yyy):

    操作 路径 方法
    无参列表 /xxx/yyy/ooo GET
    有参列表 /xxx/yyy/ooo?del=1 GET
    单条 /xxx/yyy/ooo?id=123 GET
    /xxx/yyy/ooo POST
    /xxx/yyy/ooo PUT
    /xxx/yyy/ooo DELETE

    甚至还有更小类的名,会形成/xxx/yyy/zz/ooo样式的路径,就不多举例了。

    看出优点没有?路径(不考虑参数)是一模一样的,非常省脑子,想出错都难!

    HTTP status码

    RESTful API要求必须按照国际组织规定的规范来返回状态码,但其实没几个程序员研究过这些状态码,也没必要搞那么复杂,我这个变种的规定是:

    • 200表示一切正常,包括其他的2打头的都一律用200

    • 500表示任何错误。

    • 原则上不再考虑其他状态码。

    • 不要干涉后端框架返回的状态码,因为框架返回的都是对的。

    响应体

    必有两大块:msgresult。不要有:code

    1. msg用于axios拦截器拦截,凡msg有值就一律用顶部提示组件弹一下,如果HTTP状态码是200则使用成功主题色,不是200则使用失败主题色。不需要弹的时候msg应为空串。

    2. result也就是业界常用的data,我不建议用data是因为data这个单词在业务逻辑中已经泛滥。result最大的原则就是代码必须最简

    3. 为什么不要有code?请问,已有HTTP status code为什么还要有code?如果你真的觉得200500不够用,那么可以继续增加HTTP status code,为什么要在响应体弄一个code
      有人说,code可以用于业务判断,比如支付动作,可能零钱不足、信用卡超支、花呗超支……以及成功支付,如果不用code怎么区分状态?
      废话,result不就是干这个的?不在result里放结果,放到外面干什么?如果只为了支付的时候区分状态而常设一个code,而且99.9%的概率只返回个0或者200,简直愚蠢!

    4. 其他字段:如果result是一个数组,那么,为了不破坏它的结构,其他附加的结果可以不放到result里,可以放到外面,比如下文的total字段。如果result是对象,那么外面就不要再放其他字段了。

    获取列表

    列表通常都是有参列表,因为你很可能会传页码和每页数量,除此之外,还可以有其他筛选条件:

    • 比如/xxx/ooo?del=1,用于表示所有被删除的资源。上面说过,这里不要另起接口(比如/xxx/deletedOoo),因为被删除的和没有被删除的查询逻辑相似度99%,没有必要另起接口,徒增后端复杂度和前端复杂度。

    • 再比如我收藏的资源,如果从“我的”角度出发,可以归类到“我的”大模块里,那么路径可以是:/my/favorite,而如果从资源角度出发,就可以是/xxx/ooo?favorite=1。再说复杂点,比如id为33的用户的收藏的已删除的资源,怎么表示?应表示为/xxx/ooo?userId=33&favorite=1&del=1

    • 总之,禁止给ooo这个单词改名。

    请求格式:

    {
      pageNum: 1,
      pageSize: 10,
      // 其他字段筛选条件...
    }
    

    响应格式:

    成功返回:

    {
        "total": 1,
        "result": [
            {
                "payOwner": "张三",
                "deptName": "测试小区",
                "no": "1091712103841672704",
                "payUser": "张三",
                "payMoney": 20840.00,
                "payRoom": "6-3-6-603",
                "payType": "现金支付",
                "payUserPhone": "18813265789",
                "payOwnerPhone": "18813265789",
                "payActTime": "2020-04-26T17:12:35.000+0800",
                "id": 6
            }
        ],
        "msg": "查询成功"
    }
    

    失败返回:

    {
      msg: "...失败原因..."
    }
    

    且HTTP状态码500。

    获取单条

    请求格式:

    RESTful API要求使用路径拼接方式,比如/system/user/13,但是这种方式很蠢,你在Chrome Devtools会看到这种请求:

    根本看不到资源名啊~~~

    根本看不到资源名啊~总要额外反应一下才知道是什么资源,所以,为了前端快速开发考虑,最好用传JSON方式,比如{id: 19}

    响应格式:

    成功返回:

    {
        "result": {
            "payOwner": "张三",
            "deptName": "测试小区",
            "no": "1091712103841672704",
            "payUser": "张三",
            "payMoney": 20840.00,
            "payRoom": "6-3-6-603",
            "payType": "现金支付",
            "payUserPhone": "18813265789",
            "payOwnerPhone": "18813265789",
            "payActTime": "2020-04-26T17:12:35.000+0800",
            "id": 6
        },
        "msg": "查询成功"
    }
    

    失败返回:

    {
      msg: "...失败原因..."
    }
    

    且HTTP状态码500。

    请求格式:

    {
            "payOwner": "张三",
            "deptName": "测试小区",
            "no": "1091712103841672704",
            "payUser": "张三",
            "payMoney": 20840.00,
            "payRoom": "6-3-6-603",
            "payType": "现金支付",
            "payUserPhone": "18813265789",
            "payOwnerPhone": "18813265789",
            "payActTime": "2020-04-26T17:12:35.000+0800",
        }
    

    响应格式:

    成功返回:

    {
      msg: "新增成功"
    }
    

    失败返回:

    {
      msg: "...失败原因..."
    }
    

    且HTTP状态码500。

    注意1:方法用PUT

    请求格式:

    {
            "id": 6,
            "payOwner": "张三",
            "deptName": "测试小区",
            "no": "1091712103841672704",
            "payUser": "张三",
            "payMoney": 20840.00,
            "payRoom": "6-3-6-603",
            "payType": "现金支付",
            "payUserPhone": "18813265789",
            "payOwnerPhone": "18813265789",
            "payActTime": "2020-04-26T17:12:35.000+0800"
        }
    

    响应格式:

    成功返回:

    {
      msg: "修改成功"
    }
    

    失败返回:

    {
      msg: "...失败原因..."
    }
    

    且HTTP状态码500。

    注意1:方法用DELETE

    注意2:应允许批量删,除非业务不适合批量删。

    请求格式:

    删单条 批量删
    传JSON方式,比如{id: 55} 传JSON方式,比如{id: [13,77]}
    (不推荐)路径拼接方式,比如/system/user/13 (不推荐)路径拼接方式,比如/system/user/13,77

    响应格式:

    成功返回:

    {
      msg: "删除成功"
    }
    

    失败返回:

    {
      msg: "...失败原因..."
    }
    

    且HTTP状态码500。

    相关文章

      网友评论

          本文标题:RESTful API的一个优化变种实现

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