# Web端前后端分离接口设计规范 ######版本号:V0.0.1 ## 基本规范 参考链接:[RESTful API 最佳实践](http://www.ruanyifeng.com/blog/2018/10/restful-api-best-practices.html) * 统一使用RESTful风格的接口请求方式,前端需要模拟除`GET`,`POST`以外的请求: - `GET`:读取请求,如列表,详情接口 - `POST`:创建请求,如新增一条数据 - `PUT`:更新(Update),通常更新整个实体 - `PATCH`:部分更新 - `DELETE`:删除 * URI统一使用资源实体的方式定义,资源实体统一定为英文单词的复数形式,筛选参数使用查询字段,以用户(User)实体为例 - `GET /users`:读取用户列表 - `GET /users?page=1&size=10`:分页读取用户列表(第1页,每页10条数据) - `GET /users/1`:读取id为1的用户详情 - `GET /users?source=wechat`:读取来自微信的用户 - `POST /users`: 创建用户 - `PATCH /users/1`:更新id为1的用户信息 - `DELETE /users/1`:删除id为1的用户信息 - `GET /users/1/followers`:读取id为1的用户的粉丝列表 * 统一重写HTTP状态码标识请求状态成功或失败,返回数据里不再有字段表示成功或失败,也不再有字段标识错误代码,前端需要遵循ES6规范,构建Promise对象进行ajax请求,ES6 Promise对象实现示例如下: ```Javascript var getJSON = function(url) { var promise = new Promise(function(resolve, reject){ var client = new XMLHttpRequest(); client.open("GET", url); client.onreadystatechange = handler; client.responseType = "json"; client.setRequestHeader("Accept", "application/json"); client.send(); function handler() { if (this.readyState !== 4) { return; } if (this.status === 200) { resolve(this.response); } else { reject(new Error(this.statusText)); } }; }); return promise; }; getJSON("http://rap.taobao.org/mockjs/9768/Rap/get").then(function(response) { console.log('Contents: ',response); }, function(error) { console.error('出错了', error); }); ``` - 2XX均表示请求成功: - `GET`:200,成功 - `POST`:201,创建成功 - `PUT`:200,成功 - `PATCH`:200,成功 - `DELETE`:204,已删除 - 异步处理:202,服务器已接收到请求,处于待处理状态(如异步操作)。 - 3XX表示重定向:在前后端分离时由前端控制是否跳转 - `301`:永久重定向,浏览器直接跳转 - `302`、`307`:暂时重定向,浏览器直接跳转 - `303`:暂时重定向,指定跳转URL,前端询问用户是否跳转,如 ``` HTTP/1.1 303 See Other Location: /users/1 ``` - 4XX状态码,表示前端错误 - `400 Bad Request`:无效请求,服务器不理解前端请求 - `401 Unauthorized`:用户没有提供身份凭证凭据或没有通过身份验证(如未登录,登录信息失效) - `403 Forbidden`:用户通过了验证,但是不具有访问资源所需的权限(数据权限) - `404 Not Found`:请求资源不存在或不可用(如已删除资源) - `405 Method Not Allowed`:用户已通过验证,但是所用的HTTP方法不在他的权限范围内(功能权限) - `410 Gone`:资源已从该地址转移,不再可用(如文件转移) - `415 Unsupported Media Type`:客户端要求的返回格式不支持,如只能返回JSON格式,客户端要求返回XML格式。 - `422 Unprocessed Entity`:客户端上传的实体无法处理(如数据不完整,数据校验不通过),导致请求失败。 - `429 Too Many Requests`:客户端请求的次数超过限额。 - 5XX状态码,服务端错误。要求服务端出错时要捕获异常,提供友好的信息给前端,不暴露异常信息到前端。 - `500 Internal Server Error`:客户端请求有效,服务器处理出现异常(如SQL执行错误,程序执行异常) - `503 Service Unavailable`:服务器无法处理请求,通常用于网站维护状态 ## 参数约定 * 请求参数和返回参数字段名统一使用首字母小写的驼峰格式 * 返回的字段值数据类型要保持和数据库的数据类型一致,如字符串返回的json格式需要用双引号将内容包含起来,而数值类型的不需要。 * 除对象实体外,其他类型不允许返回`null`。 * 时间类型的数据后端要将时间戳转换为可读格式,后端WEB可用的格式有`Y-M-d H:i:s`,`Y-M-d H:i`,`Y-m-d`,如对时间无特殊要求,默认为`Y-M-d H:i`,即精确到分即可。 ### 请求参数约定 __常用的请求参数必须使用下表约定的字段,不允许自定义。__ | 名称 | 参数名 | 数据类型 | 备注 | |:-------:|:---------:|:------:|:------------------------------------------------ | | 分页页码 | page | int | 第一页从1开始 | | 分页大小 | size | int | 默认值为20,最大不能超过100 | | 性别 | gender | string | male=男,female=女 | | 模糊搜索关键字 | keywords | string | 仅针对同时支持多个字段模糊检索的,如同时从商品名称和商品详情中搜索的字段 | | 身份证号 | idCard | string | 特指中国大陆身份证号,前端对输入的身份证号要进行规则校验 | | 手机号 | mobile | string | 特指中国大陆手机号(支持加+86),前端对输入的手机号要进行规则校验 | | 电话号码 | telephone | string | 包括手机号,400,800,955xx,100xx,固定电话等号码,前端要对表单数据进行规则校验 | | 姓名 | name | string | 真实姓名 | | 昵称 | nickname | string | 网络昵称 | | 邮箱 | email | string | 前端需要针对邮箱地址进行校验 | | 验证码 | captcha | string | 包括短信验证码,输入校验验证码 | | 经度 | longitude | float | 精确到小数点后6位小数 | | 纬度 | latitude | float | 精确到小数点后6位小数 | | 唯一编号 | __实体名Id | int | 如用户编号,使用userId,分类编号使用categoryId | ### 返回格式约定 返回数据遵循ES6的规范,前端能够通过返回数据构建`Promise`对象进行处理,统一采用`JWT`做鉴权,`JWT`的访问令牌`token`通过`HTTP Header`返回。 __常用的返回参数必须使用下表约定的字段,不允许自定义。__ #### 成功返回数据 | 名称 | 参数名 | 数据类型 | 备注 | |:----:|:----:|:------:|:----------------------------------- | | 数据集合 | data | Object | 返回的数据库实体数据及其业务相关数据,不同的实体分多个json对象返回 | | 其他数据 | meta | Object | 与业务不相关的数据,如分页信息 | 示例数据如下: ``` { data: { user: { id: 1, realName: "root", genderText: "女士", staffCode: "96582", lastLoginedEndpointText: "网站", lastLoginedAt: { date: "2018-12-26 11:21:40.000000", timezoneType: 3, timezone: "Asia/Shanghai" }, staffStatusText: "在职", accountStatusText: "正常" } } } ``` 分页返回示例 ``` { "data": { "list": { "id": 10, "residenceName": "in placeat", "residenceLogo": "", "buildingsCount": 0, "unitsCount": 0, "housesCount": 0, "householdersCount": 0 }, "currentPage": 1, "lastPage": 100, "size": 20, "total": 1, "from": 1, "to": 2 } } ``` #### 失败返回数据 | 名称 | 参数名 | 数据类型 | 备注 | |:--------:|:------------:|:------:|:-------------------------------------------- | | 就绪状态 | readyState | int | 4=已就绪,服务端已完成响应 | | 请求状态码 | status | int | 参考http状态码返回 | | 状态码描述 | statusText | String | http状态码返回对应的英文描述,如Unauthorized, Bad Request等 | | 响应JSON数据 | responseJSON | Object | 响应JSON数据,其中必须包含message字段,标识错误提示信息 | 示例数据如下: ``` { readyState: 4, responseJSON: { message: "手机号或密码错误" }, status: 401, statusText: "Unauthorized" } ```