RESTful接口规范

2,898 阅读10分钟

其他规范链接

JavaScript规范及命名

CSS规范及命名

Git使用规范

1. RESTful规范

RESTfulRepresentational State Transfer

资源(Resources)每种资源对应一个特定的URI(统一资源定位符),URI为每一个资源的地址或独一无二的识别符。

表现层(Representation)把"资源"具体呈现出来的形式,叫做它的"表现层",URI只代表"资源"的位置。它的具体表现形式,应该在 HTTP 请求的头信息中用AcceptContent-Type字段指定,这两个字段才是对"表现层"的描述。

状态转化(State Transfer):客户端想要操作服务器,必须通过某种手段,让服务器端发生"状态转化"。而这种转化是建立在表现层之上的,所以就是"表现层状态转化"。客户端用到的手段就是 HTTP 协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。

总结:

  • 每一个URI代表一种资源
  • 客户端和服务器之间,传递这种资源的某种表现层
  • 客户端通过四个HTTP动词,对服务器端资源进行操作,实现"表现层状态转化"

1.1 域名

应该尽量将API部署在专用域名之下。

https://api.example.com

1.2 版本

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

v1是版本号。

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

1.3 路径

路径表示 API 的具体网址。在 RESTful 架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词,而且所用的名词往往与数据库的表格名对应。

2. HTTP 请求

2.1 请求方法

2.1.1 Get

Get 请求用于从服务器取出资源(一项或多项),请求参数放入 url 中。

示例:

// 获取资源详情
/api/v1/resource/:id

// 获取资源列表
/api/v1/resource?pageNum=1&pageSize=10

2.1.2 Post

Post 请求用于在服务器新建一个资源,请求参数放入 body 中。

Post 请求有四种编码方式:

  • application/x-www-form-urlencoded

最常见的 POST 提交数据的方式,提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。

  • multipart/form-data

我们使用表单上传文件时,必须让 formenctyped 等于这个值,这种方式一般用来上传文件。

  • application/json

该方式用来告诉服务端返回的响应正文是序列化后的 JSON 字符串。这种方式可以方便的提交复杂的结构化数据。

  • text/xml

它是一种使用 HTTP作为传输协议,XML 作为编码方式的远程调用规范。用于传输 XML 结构。

2.1.3 Put

用于在服务器更新资源,请求参数可分别放入 urlbody 中。

示例:

请求地址/api/resource/:id
请求参数所要修改的资源 id 携带在 url 中,所要修改的数据放入 body 中

2.1.4 Delete

用于从服务器删除资源,请求参数放入 url 中。

示例:

请求地址/api/resource/:id
请求参数所要删除的资源 id 携带在 url 中

3. HTTP 响应

3.1 响应体

参数类型说明
codeNumber状态码
messageString显示成功信息 / 错误信息
dataObject / Array返回的数据 / 数据列表

示例:

// 当数据为空时,data为null或[]
{
  "code": 200,
  "message": "请求成功",
  "data": {
    ...
  }
}

3.2 状态码

codemessage说明使用场景
200请求成功Ok所有成功的请求中。
201创建xx成功Created服务器创建数据成功时。
202已接收请求,处理中Accept短信发送、邮件通知、模板消息推送等耗时较长需要队列支持的场景。
204删除成功 / 更新成功No Content使用 Delete 删除资源成功时,或使用 Put 更新资源成功时。
301请求的资源已被永久迁移Moved Permanently请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替。
302请求的资源被临时迁移Found临时移动。与301类似,但资源只是临时被移动,客户端应继续使用原有URI。
304所请求的资源未修改Not Modified所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源。
400请求语法错误Bad Request客户端请求的语法错误,服务器无法理解。
401身份未认证Unauthorized未进行身份认证的用户访问需要认证的API时,或token无效 / 过期时。
403权限不足Forbidden该状态码可以理解为没有权限访问该请求,服务器收到请求但拒绝提供服务。例如当普通用户请求操作管理员用户时。
404资源未找到Not Found当用户请求的资源不存在时,都必须返回该状态码。若该资源已永久不存在,则应该返回 410 响应。
405HTTP 请求方法不被允许Method Not Allowed客户端请求中的方法被禁止,当客户端使用的 HTTP 请求方法不被服务器允许时,必须返回该状态码。该响应必须返回一个带有 Allow 的响应头信息用以表示出当前资源能够接受的请求方法的列表。
406不支持的数据格式Not Acceptable服务器无法根据客户端请求的内容特性完成请求。当 API 在不支持客户端指定的数据格式时,应该返回此状态码。例如支持 JSONXML 输出的 API 被指定返回 YAML 格式的数据时。(Http 协议一般通过请求首部的 Accept 来指定数据格式)
408客户端请求超时Request Time-out服务器等待客户端发送的请求时间过长,超时。当客户端请求超时的时候必须返回该状态码,需要注意的是,该状态码表示 客户端请求超时,在涉及第三方 API 调用超时的时候,不可返回该状态码。
409请求存在冲突Conflict服务器完成客户端的 PUT 请求时可能返回此代码,服务器处理请求时发生了冲突。该状态码表示因为请求存在冲突无法处理。例如通过手机号码提供注册功能的 API ,当用户提交的手机号已存在时,必须返回此状态码。
410该资源永久被删除Gone客户端请求的资源已经不存在。 410 不同于 404 ,如果资源以前有现在被永久删除了可使用 410 代码,可通过 301 代码指定资源的新位置。
413请求数据过大Request Entity Too Large由于请求的实体数据过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个 Retry-After 的响应头,告知客户端可以在多少时间后重新尝试访问。
414请求的url过长Request-URI Too Large请求的URI过长,服务器无法处理。
415不允许上传的图片格式Unsupported Media Type服务器无法处理请求附带的媒体格式。例如只允许上传图片格式的文件,但是客户端提交媒体文件非法或不是图片类型,这时应该返回该状态码。
429请求次数过多Too Many Request该状态码表示用户请求次数超过允许范围。例如 API 设定为 60次/分钟,当用户在一分钟内请求次数超过 60 次后,都应该返回该状态码。并且在响应头中加入相应内容。
500服务器错误Internal Server Error服务器内部错误,无法完成请求。该状态码必须在服务器出错时抛出。
503服务器维护中Service Unavailable由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的 Retry-After 响应头信息中。
10000+自定义code任何自定义code,需返回大于10000以上的数字

4. 应用场景

4.1 获取单个资源

请求方法Get
请求地址/api/resources/:id /* 不推荐 */ /api/getResourceById
请求参数所要获取的资源 id 携带在 url 中

响应体:

{
  "code": 200,
  "message": "请求成功",
  "data": {
    "id": 1,
    "nickname": "west",
    "username": "myName"
  }
}

4.2 获取资源列表

4.2.1 无需分页时

请求方法Get
请求地址/api/resources/* 不推荐 */ /api/getResourseList

响应体:

{
  "code": 200,
  "message": "请求成功",
  "data": [
    {
      "id": 1,
        "nickname": "west",
        "username": "myName1"
    },
    {
      "id": 2,
        "nickname": "east",
        "username": "myName2"
    },
    ...
  ]
}

4.2.2 需要分页与排序时

请求方法Get
请求地址/api/resources/* 不推荐 */ /api/getResourseList

请求参数:

// 参数携带在url中
{
  // 必须,当前页码,统一用pageNum
  "pageNum": 1,  
  // 必须,每页显示条数,统一用
  "pageSize": 10,   
  // 排序,值格式为"property,type",type可选值为desc、asc
  "orderBy": "createTime,desc",
  // 其他条件
  "searchCondition": "***",
  ...
}

响应体:

// 需要分页时将数据集存放在data的items内,total表示总条数
{
  "code": 200,
  "message": "请求成功",
  "data": {
    // 必须,列表数据集
    "items": [
      {
        "id": 1,
        "nickname": "west",
        "username": "myName1"
      },
      {
        "id": 2,
        "nickname": "east",
        "username": "myName2"
      },
      ...
    ],
    // 必须,表示总条数
    "total": 100
  }
}

4.3 创建资源

请求方法Post
请求地址/api/resources/* 不推荐 */ /api/createResource

请求参数:

// 请求参数放入body中
{
  "name": "张三",
  "phone": "11011011011",
  ...
}

响应体:

// 是否返回响应数据可协商(前端在判断创建成功后可通过刷新列表拿到最新数据)
{
  "code": 201,
  "message": "创建成功"
  // No Content, 不返回数据(可协商)
}

4.4 修改资源

请求方法Put
请求地址/api/resources/:id/* 不推荐 */ /api/updateResource

请求参数:

// 所要修改的资源id携带在url中,要修改的数据放在body内
{
  "name": "张三",
  "phone": "11011011011",
  ...
}

响应体:

// 是否返回响应数据可协商(前端在判断更新成功后可通过刷新列表拿到最新数据)
{
  "code": 204,
  "message": "更新成功"
  // No Content, 不返回数据(可协商)
}

4.5 删除资源

请求方法Delete
请求地址/api/resources/:id/* 不推荐 */ /api/deleteResourceById
请求参数所要删除的资源 id 携带在 url 中

响应体:

{
  "code": 204,
  "message": "删除成功"
  // No Content, 不返回数据
}

5. API 命名规范

5.1 面向资源命名

在面向资源的 API 中,资源名称API 服务名称集合 ID 资源 ID 构成,按分层方式组织并以正斜杠 / 分隔。如果资源包含子资源,则子资源的名称由父资源名称后跟子资源的 ID 组成,也以正斜杠分隔。如下表。

便捷之处是,通过拆分资源名称(例如 name.split("/")[n]),可以获得单个集合 ID 和资源 ID(假设任何段都不包含正斜杠)。

API 服务名称集合 ID资源 ID集合 ID资源 ID
//storage.xxx.com/buckets/bucket_id/objects/object_id

完整资源名称:

//library.com/shelves/shelf_1/books/book_2

相对资源名称:

shelves/shelf_1/books/book_2

5.2 URL命名方式

  • 集合 ID 必须是 复数 形式的首字母 小写驼峰 体。如果该词语没有合适的复数形式,则应该使用单数形式。

  • 必须是 易读 的且 简明扼要 的英文词语。

  • 避免过于笼统的词语,应对其进行 限定 后再使用。例如,rowValues 优先于 values。而且应该避免在不加以限定的情况下使用以下词语:

    • elements
    • entries
    • instances
    • items
    • objects
    • resources
    • types
    • values
  • URL 中不能出现 -,必须用下划线 _ 代替。