基于工程经验的『RESTful接口设计规范』

前言

这篇文章,主要想总结本身在设计RESTful API的一系列经验于思考。前端

有些规范可能与标准规范有所出入,可是全部的考量都是基于『减小重复工做,增长可读性可维护性』而出发的。话说回来,我一直以为 RESTful API 设计,确实没有很明显的公认规范(若是你是指发明者的那篇论文,估计没多少人详细阅读过,并且其做者只是提出了一系列概念而已)。网上的教程,彷佛都是千篇一概的(我严重怀疑:都是 “借鉴or拷贝” 阮一峰老师的那几篇文章),僵硬并且呆板,有点教条化(历来没有人怀疑它们吗,反正我按照这些教条设计API,没有感觉到多少乐趣)。数据库

以上,并非所有否认,好东西要充分吸取,很差的东西,要融合本身的理解,加以改造。后端

对 RESTful API 的认识

说到这个,彷佛又要谈及『RESTful 是对资源的抽象』、『结合了HTTP 的特色』云云。不过这些都是一些没用的套话,没啥养分价值,而我想从另外的角度谈论这个。安全

既然是 API,通常都符合 API 的通常模式:bash

ResultType ApiName(ParamType )

1. 接口参数,即形参。能够是 string,int,以及其余任意能够称之为参数的东西
2. 接口返回值。能够是 string,int,以及其余任意能够称之为返回值的东西
3. 接口名(签名)
复制代码

咱们来看看 RESTful 是如何对应上这个模式的:网络

HttpResponse URL(HttpRequest)

1. HttpRequest:包括请求头,URL参数,请求body参数
2. HttpResponse: 包括响应头,响应的body
复制代码

这样来看,RESTful API 无非是一种特殊的API 而已,通用的 API 设计法则,一样适合 RESTful,只不过非变换形式而已。架构

那么咱们大概有哪些比较通用的标准呢?大概有这些:ide

  1. 接口命名,必须作到清晰。通常来讲,作到『动宾短语』便可。
  2. 接口数量,越少越好。三个不如两个,两个不如一个,一个不如没有,最好的 API 就是『没有API』。
  3. 有明确的输入输出。念念不忘必有回响,老是有返回值,告诉调用端,我到底作了什么,作得怎么样,即:反馈。

下面就来看看这些标准,是如何影响下文的内容的,:)。spa

URL设计,及其反模式

URL 就是接口签名,而签名必须作到清晰,没有歧义。设计

有统一的前缀 & 版本化

若是后端架构是服务化的,那么有可能每一个服务会对外提供公共的 RESTful API,那么有个统一的前缀格式,会比较好,好比:

/SERVICE_NAME/v1/users
or
/APP_NAME/v2/users
复制代码

尽可能短小

同一份资源,能够有不一样的路径,去理解它。好比:

User -- 1:N --> Server-- 1:N --> Client ... 更加复杂的实体映射关系

1. /users/{user_id}/servers/{server_id}/clients
2. /clients

通常你们倾向于选项 1(可是实体关联关系特复杂时,会缩短URL),
不过选项2 也是一个不错的选择,总而言之,口味问题吧。
复制代码

数量尽可能少

接口数量越少越好,能合并的接口就尽可能合并。好比,这样的状况:

获取用户列表信息:GET /users
获取单个用户信息:GET /users/{id}

坦白说,获取一个与获取一批,彷佛并无什么语义上的差异,
可是后端的同窗就不同了,他可能须要写两个 View Class。
因此只保留批量的接口,查询一个时,用 URL 参数传递就好了。
复制代码

这样的状况:

PUT /users/{id}
PUT /users

直接合并到一个接口里面作就好了,PUT 一个 user与 PUT 一群 user,有啥本质的不一样吗?
复制代码

还有这样极端的状况:

DELETE /users/{id}

删除一个user与删除一批user,有啥不一样?
若是要一次删除100 个 user,难道让前端同窗,调 100 次这个接口?
多一次调用,就多一次风险(如网络问题),
这个时候就别守着 RESTful 那些个教条了,接口的可用性、效率性,更加剧要。

这个时候,不如设计成这样(至于 DELETE 接口能不能传Request body,这里不讨论):
POST /users_deletion
{
    "user_ids": [1, 2, 3, 4, 5]
}
复制代码

返回值设计

前面有说到,HttpResponse中,咱们能够利用:

Response Headers
能够作少许文章,如自定义一个Header

Status Code
按照基本规范来,该404的404,该200的200

Response body
基本都是围绕这个作文章
复制代码

Response body 既要能正常返回信息,出错了也要告诉出错缘由(错误码),出错详情。因此咱们大概能够设计成这样:

{
    是否成功
    boolean "is_success":
    错误码是多少
    number|null "err_code":
    错误信息
    string|null "err_msg": 
    错误详情(可选)
    string|null "err_detail":
    出错的时哪一个服务
    string|null "provider": 
    
    正常返回时的数据
    "response_data": {

    }
}
复制代码

这样,前端调用 API ,就有章法可循了,不至于盲目。

字段命名规范

没有很明确的规范,可是尽可能跟随数据库的风格,即:下划线风格。 这样,在 序列化整个 Model 时,也许会很方便。

其余规范

接口限流

参考 GitHub 的风格。

接口安全

这个无法系统化,能够参考网络上相关文章。

相关文章
相关标签/搜索