Restful API 开发规范

统一响应体格式

返回值统一为json格式,最外层只包含 codemsgdata 三个字段,接口返回包含数据内容时,仅使用 data 字段。

{
	"code":"错误码,成功为0",
	"msg":"返回的(错误)描述信息,不能有堆栈信息",
	"data":{数据}
}

响应举例

空响应-成功:
{
	"code":"0",
	"msg":"",
	"data":null
}
空响应-出错:
{
	"code":"0xaabc100f",
	"msg":"username can't be null",
	"data":null
}
单值响应:
{
	"code":"0",
	"msg":"",
	"data":{
	    "username": "cnlym",
	    "nickName": "产码机器"
	}
}
多值响应(分页)
{
	"code":"0",
    "msg":"",
	"data":{
		"total":11, //总条数
		"pageNo": 1,  //当前页
		"pageSize":20, //当前分页记录数
		"list": [{  //分页内容
			"userId": 1,
			"name": "admin"
			},{
			"userId": 2,
			"name": "leader"
		}]
	}
}
多值响应(不分页)
{
	"code":"0",
    "msg":"",
	"data":{
	  "total":11,
	  "list": [{  //分页内容
      			"userId": 1,
      			"name": "admin"
      			},{
      			"userId": 2,
      			"name": "leader"
      		}]
	}
}

统一 api 文档约束

为了便于对接,组件 doc 目录下须包含以下文件

  • api.json

    • 统一使用 swagger json 文档

      • 需要指定 info-title, description,version,contact

      • basePath 对应 context 值,格式为:/<appId>

  • api.md

    • api文档,包含如下,不描述则采用本文的推荐设计:

      • 简介

      • 认证

      • 鉴权规则

      • 安全传输与加密算法

      • 返回值规则

      • 空响应

      • 单值响应

      • 多值响应(分页)

      • 多值响应(不分页)

  • ext.md

    • swagger 返回值无法描述泛型等,额外标注说明

  • guidance.md

    • 编程指引

  • appendix.md

    • 附录,错误码、数据字典、翻译项、复杂参数解释

  • <appId>-api-sdk.jar

    • 接口sdk

Restful 请求方法含义

类型

说明

GET

从服务器取出资源

POST

在服务器新建一个资源,修改一个资源或者删除一个资源

PUT

在服务器更新资源(客户端提供改变后的完整资源)

DELETE

从服务器删除资源

HEAD

获取资源的元数据

PATCH

在服务器更新资源(客户端提供改变的属性)

OPTIONS

获取信息,关于资源的哪些属性是客户端可以改变的

常用 HTTP 状态码

HTTP状态码 说明

200 OK

服务器成功返回用户请求的数据。处理成功时默认该值。

201 Created

修改数据成功(返回之前已经入库)

202 Accepted

表示一个请求已经进入后台排队(异步任务)

204 No Content

表示请求成功但无返回值,可用于修改,删除

301 Moved Permanently

资源的URI已被永久更新

302 Found

资源URI重定向,与301类似(临时)

304 Not Modified

资源未更改,客户的缓存资源是最新的, 请客户端使用缓存(缓存),ES-ik插件的动态更新用到了这个

400 Invalid Request

用户发出的请求有错误,是无效请求,如字段映射不正确,参数不正确都可以用这个

401 Unauthorized

需要先进行认证(登录)

403 Forbidden

服务器拒绝执行,一般是由于权限不够,也可能ip进了黑名单等

404 Not Found

用户发出的请求是针对不存在的记录

405 Method Not Allowed

不允许执行目标方法,如只允许POGT却使用GET,响应中应该带有 Allow 头,内容为对该资源有效的 HTTP 方法

406 Not Acceptable

用户请求的格式不可得,如只有 abc.txt,浏览器期望的MIME类型没有txt

410 Gone

用户请求的资源被永久删除,且不会再得到

422 Unprocesable entity

参数格式正确,但语义错误,浏览器将它与400处理方式相同,因此也可以使用400

429 Too Many Request

请求过多,触发限流时,可用于反爬虫,418(触发彩蛋)也可用于反爬虫

500 Internal Error

服务器发生错误,用户将无法判断发出的请求是否成功

丢失更新问题

HTTP 201 可以包含一个ETag响应头字段,指示刚刚创建的请求变量的实体标签的当前值。ETag头字段可以在以后的条件请求中使用,以防止“丢失更新”问题。

当多人编辑资源而不了解彼此的更改时,会发生丢失的更新问题。在这种情况下,最后一个更新资源的人“获胜”,之前的更新将丢失。ETag可以与If-Match标头结合使用,让服务器决定是否应该更新资源。如果ETag不匹配,则服务器通过412 (Precondition Failed)响应通知客户端。

数据库中添加dataVersion,每次修改+1,可以使用该字段来避免并发更新问题。

请求头约束

命名规则

单词首字母大写,单词与单词间使用中划线(-)分割。如:User-Agent

请求头保留字段

参数名 类型 必选 说明

User-Agent

string

终端类型

Token

string

接口认证使用:身份认证信息,采用 base64 编码。

X-Sid

string

×

秘钥协商使用:安全会话 ID。

X-Dk

string

×

秘钥协商使用:使用协商密钥加密的 数据密钥

User-Id

string

×

用户 ID

Trace-Id

string

用于标识一笔业务的唯一序号,UUID 格式

Span-Id

string

用于标识某一阶段调用序号,32位字母或数字

Biz-Id

string

×

业务标识

X-B3-TraceId

hex string

UUID 格式

X-B3-SpanId

hex string

64 位值,采用小写 16 进制字符显示

X-B3-ParentSpanId

hex string

64 位值,采用小写 16 进制字符显示

X-B3-Sampled

boolean

×

0 – 不采样, 1 – 采样

X-B3-Flags

string

×

1 – debug,要记录本次所有调用链信息

请求体约束

除文件和表单数据外,POSTPUT 等带请求体的方法,请求体统一为 JSON 格式,

请求参数要求

参数须提供 取值范围格式限制枚举限制

时间字段和格式

  • 当查询条件需要使用起止时间时,参数名统一采用 beginTimeendTime

  • 采用 ISO8601 格式,使用带 Time-zone 的标准时间格式,如:2020-7-13T00:00:00.000+08:00;

字符串和编码
  • 字符串的所有操作统一使用 UTF-8 编码。

  • 长度限制如下

场景 推荐长度

ID、标识、名称、别名

64, 128

描述、备注、文件名(全路径)

512, 1024

详情

2048

文本、文件

不限制

常用字段约束

统一常用的参数名称

分页查询参数

demo: 每页20条记录,查询第一页,先按照 username 正序排序,再按照 phoneNo 逆序排序

{
	"pageNo":"1",
	"pageSize":"20",
	"conditions": [
        {
	        "property": "username",
	        "like": "cn"
	    },{
            "property": "level",
            "equal": "vip"
        }
	],
	"orderBy":[
	    {
	        "property": "username",
	        "direction": "asc"
	    },{
            "property": "phoneNo",
            "direction": "desc"
        }
     ]
}
用途 参数名 举例

查询页码

pageNo

1

分页大小

pageSize

20

排序参考

sortBy

["name"]

排序规则

order

"asc"

分页查询参数名称

参数字段顺序

  • 标识性字段(id、name)

  • 必填字段(sex)

  • 常用字段(phone)

  • 描述性字段(note)

  • 通用型字段(updateTime)

统一错误码格式

版本号设计

软件中任何事物都有变的可能性,api 接口也是这样的,因此需要在 api 的请求路径中添加版本号。如 /api/xxService/v2/**

安全传输

参考 密钥协商

编码注意事项

  • 定义统一返回值类 BaseResponse,且该类只能在接口层使用

  • 所有 Controller 层接口函数统一返回 BaseResponse,或使用全局返回值自动包装

  • 入参,返回值尽量不要有 Map

  • Controller 层进行 DTO 转换,不允许将 DTO 传递倒业务层

  • Controller 不要出现 Request,Response 这类对象

  • 一般不需要在这里打印日志,异常处理,使用统一的日志打印

  • 注意防枚举(id有顺序)、防重放

Ajax vs Restful RPC api 接口

  • 虽然两者都是 HTTP协议 JSON 格式

  • Restful 是无状态的,属于 RPC 的一种形式,职责为服务间通信。校验主要为 token 认证。

  • Ajax 是前后端局部刷新增加用户体验的。校验包含各种网络攻击。