Skip to content
李文富 edited this page Mar 12, 2020 · 8 revisions

Table of Contents

设计思想

  • 一致:严格遵循规范,避免概念冲突
  • 明确:接口一目了然,使用者通过查看地址、方法即可大致理解接口意图,并可以猜测到数据结构
  • 简洁:能省则省,能够用推断、计算得出的数据,云端不应提供

REST

  • API 上的资源建议都采用 uuid 做为唯一标识
  • 对于超长(1K)的 GET URL,可以采用 POST 来代替
  • 版本,使用 URL 形式 {http_method} /{version}/{resources}...,如 GET /v0.3/products/01234567-89ab-cdef-0123-456789abcdef
  • 非标准 HTTP Verb,采用 POST /{resources}/{resource_id}/actions/{action} 的方式
  • CRUDL(create/retrieve/update/delete/list)中 L 的方案参考 OData,接口返回的是数组数据,必须返回以下结构,即使用一个具备有 items 属性的对象进行包裹
<syntaxhighlight lang="JavaScript"> { "items": [], "count": 20 } </syntaxhighlight>

Resource URL

  • Resource URL(最后一个单词为单数小写,表示用途归类)
  • 仅用来表示资源的路径(不应包括业务参数),及一些特殊的actions
  • 以复数(名词)进行命名,不管返回单个或多个资源
  • 使用小写、数字及下划线(下划线用来区分多个单词,为了与 JSON 对象及属性的命名方案保存一致不使用连字符“-”)
  • 资源的路径从根到子依次如下
  /{resources}/{resource_id}/{sub_resources}/{sub_resource_id}/{sub_resource_property}
  如 GET /projects/{projectId}/apps/{appId}
  • 当 resource 的仅仅用于归类用途时,而不是具体的资源或层级关系,应该使用小写和单数。如 /user/

DTO

  • 资源都建议使用 uuid 作为唯一的标识,使用 8-4-4-4-12 的格式小写 uuid,命名为 id
  • JSON 中的 key 采用小驼峰风格命名,如 accessToken
  • 日期,建议采用 ISO-8601 的规范,如(1994-11-05T13:15:30Z),在一些场合下也可以采用 Unix time

VERBS(CRUDL)

POST(C)

  • 创建资源
  • 执行资源的 actions
  • 超长的 GET 请求
POST /projects POST /projects/{projectId}/apps/{appId}/actions/release POST /projects/{projectId}/apps/{appId}/query

GET(R)

  • 获取资源
  • 查询资源(列表、分页)
GET /projects GET /projects/{id}

PUT/PATCH(U)

  • 更新资源(PATCH 局部更新、PUT 全量更新)
PUT /projects/{id} PATCH /projects/{id}

DELETE(D)

  • 删除资源
DELETE /projects/{id} DELETE /projects/{id1},{id2},{id3}...

返回结果

状态码 HTTP_STATUS_CODE

  1. 属于临时响应请求,通常表示请求已被接受,但还需要继续处理 // 1xx Informational
  2. 属于成功的请求 // 2xx Success
  3. 200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。
  4. 201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
  5. 202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
  6. 204 NO CONTENT - [DELETE]:用户删除数据成功。
  7. 属于转向或通知请求 // 3xx Redirection
  8. 属于客户端请求有误 // --- 4xx Client Error ---
  9. 400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。
  10. 401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
  11. 403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。
  12. 404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。
  13. 406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。
  14. 410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。
  15. 422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。
  16. 属于服务器错误 // --- 5xx Server Error ---
  17. 500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。

响应结果 HTTP_RESPONSE

GET /projects:返回资源对象的列表(数组) GET /projects/{id}:返回单个资源对象 POST /projects:返回新生成的资源对象 PUT /projects/{id}:返回完整的资源对象 PATCH /projects/{id}:返回完整的资源对象 DELETE /projects/{id}:返回一个空文档

认证与授权

  • 待续

查询(L)方案

URI 的结构

  • 为了区分与业务的参数进行区分,所有的 query options 使用 $ 开头

query options

?$limit=10:指定返回记录的数量 ?$offset=10:指定返回记录的开始位置。 ?$orderby=name asc:指定返回结果按照哪个属性排序,以及排序顺序。 ?reviewStatus=ok:指定筛选条件

$filter

  • $filter 相当于 SQL 中的 where,语法为 filter={field} {operate} {value},如 name eq 'myname'
  • 运算符优先级,较高位置的运算符“与其他运算符相比,将更紧密地绑定到其操作数”。例如,and 的优先级高于 or,比较运算符的优先级高于其中任何一个运算符
运算符
逻辑运算符 not
比较运算符 eq、ne、gt、lt、ge、le
逻辑运算符 and
逻辑运算符 or
  • 基于性能及实现的考虑, 不支持 ne 不等于, 仅支持单个字段的条件查询

$orderby

  • 排序,语法为 orderby={field} [asc|desc]
  • 仅支持单个字段的排序
  • {field} 为查询资源的字段名称 [asc|desc] 排序的方向,默认为 asc

$select

  • 确定在查询结果集中返回每个文档的哪些字段
  • $Select参数分为两种形式:
    1. 单个星号(*),指示应返回所有可检索字段,或
    2. 以逗号分隔的字段路径列表,用于标识应返回哪些字段。
  • 如果您在未显式指定其子字段的情况下列出了复杂字段,则所有可检索的子字段都将包含在查询结果集中。

$offset

  • 分页参数,指示记录起始位置,默认 0

$limit

  • 分页参数,指示页大小,默认 10

$count

  • 是否返回总计数,默认 false,不返回

返回结果

仅返回数据

<syntaxhighlight lang="JavaScript"> { "items": [] } </syntaxhighlight>

返回数据与总条数

  • 请求参数 $count=true
<syntaxhighlight lang="JavaScript"> { "items": [], "count": 20 } </syntaxhighlight>

仅返回总条数

  • 接口功能为计数接口,否则不提供选项
<syntaxhighlight lang="JavaScript"> { "count": 20 } </syntaxhighlight>

通用错误码

HTTP_CODE STATUS_CODE CODE MESSAGE 备注
BAD_REQUEST 400 BIZ_CODE/INVALID_ARGUMENT 参数XX缺失 客户端请求错误, 不提示给用户

错误对象

  • 当接口出现非 2xx 的 HTTP(2xx时候,不能返回错误类型)响应时,采用返回统一 HTTP 响应信息
<syntaxhighlight lang="JavaScript"> HTTP/1.1 400 BAD REQUEST Content-Type: application/json { "code": "APP/INVALID_ARGUMENT", "message": "{error message}", "request_id": "a2888e60-83a9-4575-878e-3a0df752e7e2", "host_id": "{server identity}", "server_time": "2019-10-31T11:47:49.872+08:00" } </syntaxhighlight>
  • 错误规范使用三层信息:http status code、code、message

错误对象说明

  • 错误对象字段说明
    • http status code:符合 HTTP 协议的响应状态码
    • code:用来表示某类的错误,如缺少参数、类型不匹配等等,用来对 http status code 进行扩展,开发人员可以据此进行错误的细节处理
    • message:为错误的摘要信息,并且应该包含对用户处理该错误有指导意义的信息
    • request_id:错误的 uuid,用于帮助技术人员在日志系统中获得错误的详细
    • host_id:为发生错误的服务器
    • server_time:为发生错误时的服务器时间
  • code 命名规范
    • 采用大写字母单词命名,单词与单词之间用下划线(_)加以分割
    • 采用 {biz_name}/{error_code} 的命名结构, 其中 {biz_name} 为业务名称的缩写(可选),如 IM 等。UC/SERVICE_NOT_AVAILABLE
  • code 定义与使用规则
    • code 应以错误类别来定义,而非具体的某错误
    • code 要能准确标识错误,因为业务需要依赖此进行二次开发
    • 使用系统已经定义好的错误 code,见 #系统错误 code
    • 当错误发生在某个系统上,应该加上 {biz_name}/ 前缀,如 APP、USER 等等,见 BIZ_NAME

BIZ_NAME

BIZ_NAME 业务名 备注
USER 用户服务 用户账号、用户信息等
APP 应用服务 移动 Hybrid 应用服务

Clone this wiki locally