原创

RESTful API接口设计规范

RESTful API是目前比较成熟的一套互联网应用程序的API设计理论。

REST(Representational State Transfer)表述性状态转换,REST指的是一组架构约束条件和原则。 如果一个架构符合REST的约束条件和原则,我们就称它为RESTful架构。REST本身并没有创造新的技术、组件或服务,而隐藏在RESTful背后的理念就是使用Web的现有特征和能力, 更好地使用现有Web标准中的一些准则和约束。虽然REST本身受Web技术的影响很深, 但是理论上REST架构风格并不是绑定在HTTP上,只不过目前HTTP是唯一与REST相关的实例。

稳定性、接口的跨域性、接口的协议规则、接口的路径规则、接口单一原则、接口过滤和接口组合等诸多因素

一、规范性建议

1. 职责原则

在设计接口时,必须明确接口的职责,即接口类型,接口应解决什么业务问题等

2. 单一性原则

在明确接口职责的条件下,尽量做到接口单一,即一个接口只做一件事,而非两件以上。

3. 协议规范

在设计接口时,应明确接口协议,是采用HTTP协议,HTTPS协议还是FTP协议,要根据具体情况来定。HTTPS=HTTP+SSL,适用于对安全性要求较高的业务情景。HTTP协议,适用一般对安全性要求比较低或没要求的业务情景。FTP协议是一套标准的文件传输协议,用于传输文件,如.txt,.csv等,一般文件传输,采用FTP协议。

4.URI路径规则

由于API获取的是一种资源,所以网址URI中尽量为名词,而非动词;URI中的名词表示资源集合,使用复数形式;不用大写;用中杠-不用下杠_;避免层级过深的URI。

GET         /zoos:列出所有动物园
POST        /zoos:新建一个动物园
GET         /zoos/ID:获取某个指定动物园的信息
PUT         /zoos/ID:更新某个指定动物园的信息(提供该动物园的全部信息)
PATCH       /zoos/ID:更新某个指定动物园的信息(提供该动物园的部分信息)
DELETE      /zoos/ID:删除某个动物园
GET         /zoos/ID/animals:列出某个指定动物园的所有动物
DELETE      /zoos/ID/animals/ID:删除某个指定动物园的指定动物

应该将API的版本号放入URL。如:

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

将版本号放在HTTP头信息中,但不如放入URL方便和直观

req.setRequestHeader("Accept", "vnd.example-com.foo+json; version=1.1");

$.ajax({
    beforeSend: function (req) {
        req.setRequestHeader("Accept", "vnd.example-com.foo+json; version=1.1"); 
    },
    type: "GET",
    url: "http://http://www.example.com/foo/12",
    success: function (data) {
        /* code elided */
    },
    dataType: "json"
});

一般地,域名分为主域名和专有域名,主域名适合API长期不变或变化较少的业务,专有域名是解决具体的专有业务的。
建议将API部署在专有域名下,以此屏蔽消费者对服务提供方的部署细节(可借助于平台的反向代理+路由网关)

https://api.example.com
https://example.com/api/

5.Http请求方式

接口基本访问协议:GET(获取)、POST(新增)、PUT(修改)、DELETE(删除)

GET     /zoos:列出所有动物园

GET     /zoos/ID:获取某个指定动物园的信息

POST    /zoos:新建一个动物园

PUT     /zoos/ID:更新某个指定动物园的信息(提供该动物园的全部信息)

DELETE  /zoos/ID:删除某个动物园

6.跨域考虑

在明确域名的情况下,一定要考虑接口是否跨域,以及跨域应采用的技术手段等。

7.适度过滤信息

如果记录数量很多,服务器不可能都将它们返回给用户。API应该提供参数,过滤返回结果。

当记录数比较多时(如 select id,name,age from zoos),应适当添加一些条件对数据进行过滤,如TOP,分页,分组,排序和WHERE条件等

?limit=10:指定返回记录的数量
?offset=10:指定返回记录的开始位置。
?page_number=2&page_size=100:指定第几页,以及每页的记录数。
?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。
?animal_type_id=1:指定筛选条件
参数的设计允许存在冗余,即允许API路径和URL参数偶尔有重复。比如,
GET /zoo/ID/animals 与 GET /animals?zoo_id=ID 的含义是相同

8.返回数据格式

一方面,出于平台标准化的API管理,另一方面,遵循微服务的宽进严出设计理念,建议RESTful采用标准的Json格式。返回结果为统一的json格式。返回数据格式,一般包括三个字段。

失败情况(状态码、错误码和错误描述)
{
   "status":0,     //状态码 0-表示失败,1-表示成功
   "error_code":”2003”,//错误码,一般在设计时定义
   "error_des":”身份验证失败”//错误描述,一般在设计时定义
}

成功情况(标识id,数据对象,状态码)

{
    "status":1,    //状态码 0-表示失败,1-表示成功
    "sid":"sh20190111",  //Token id
    "users": {
          "id":"al201901111341",   //用户id
          "name":"xf98_云雀code"//用户名称
          "addr":"福建福州鼓楼区" //地址区域
     }
}


{
    "status":1,    //状态码 0-表示失败,1-表示成功
    "sid":"sh20190111",  //Token id
    "data":{
          "id":"al201901111341",   //用户id
          "name":"xf98_云雀code",//用户名称
          "addr":"福建福州鼓楼区",//地址区域
          "job":{
                "id":"1b434wtert564564sdffeyey", //任务ID
                "jobName":"任务名称” 
          }
     }
}

9.安全性原则

接口暴露的考虑,接口并发量的考虑,接口防攻击的考虑,接口跨域的考虑等。
安全性:不会改变资源状态,可以理解为只读的;
幂等性:执行1次和执行N次,对资源状态改变的效果是等价的;

方法 安全性 幂等性
GET
POST × ×
PUT ×
DELETE ×

10.可扩展性原则

在设计接口时,充分考虑接口的可扩展性。

11.定义API界限

任何API,从权限上,可归结为匿名API和非匿名API,前者不需要验证,后者需要验证。

12.定义API返回码

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

常见状态码

1)  200 OK                [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)

2)  201 CREATED           [POST/PUT/PATCH]:用户新建或修改数据成功

3)  202 Accepted          [*]:表示一个请求已经进入后台排队(异步任务)

4)  204 NO CONTENT        [DELETE]:用户删除数据成功

5)  400 INVALID REQUEST   [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的

6)  401 Unauthorized      [*]:表示用户没有权限(令牌、用户名、密码错误)

7)  403 Forbidden         [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的

8)  404 NOT FOUND         [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的

9)  406 Not Acceptable    [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)

10)  410Gone              [GET]:用户请求的资源被永久删除,且不会再得到的

11)  422Unprocesable entity   [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误

12)  500INTERNAL SERVER ERROR [*]:服务器发生错误,用户将无法判断发出的请求是否成功

13.异步任务

对耗时的异步任务,服务器端接受客户端传递的参数后,应返回创建成功的任务资源,其中包含了任务的执行状态。客户端可以轮训该任务获得最新的执行进度。如果任务的执行状态包括较多信息,可以把“执行状态”抽象成组合资源,客户端查询该状态资源了解任务的执行情况。

二、反规范性建议

存在这样一种业务场景:某个接口需要返回多个api接口组合的结果 ,在类似的业务场景下,所设计的接口,具有一定的反规范性。

请求:
data:[
    {url:'api1',type:'get',data:{...}},
    {url:'api2',type:'get',data:{...}},
]

响应:
{
    status:0,
    msg:'',
    data:[
        {status:1,msg:'',data:[]},
        {status:1,msg:'',data:{}}
    ]
}

三、API扩展事项

1、RESTful API依托PaaS平台治理,需要对API进行认证、授权、参数加密等操作,可考虑在HTTP头部加认证token、调用链指令、状态信息等系列信息。

2、API分层,会有内部API和外部API之分,两种API的设计或有不同。

3、对于API设计的状态选择,建议为无状态、N次幂等,但后续或存在性能优化问题。

4、建议了解下GraphQL

正文到此结束
该篇文章的评论功能已被站长关闭