RESTful API定义及使用规范

首发于fxm5547的博客html

RESTful自己是一种风格而不是规范,本文为该风格的规范实现的最佳实践,本文档详细说明了HTTP RESTful API的定义和使用规范,做为接口调用者和实现者的重要参考。android

接口风格

遵循RESTful设计风格,同时控制复杂度及易于使用,仅遵循大部分原则。 遵循原则:ios

  • 使用https协议
  • 版本号放入URL或Header
  • 只提供json返回格式
  • post,put上使用json做为输入
  • 使用http状态码做为错误提示
  • Path(路径)尽可能使用名词,不使用动词,把每一个URL当作一个资源
  • 使用HTTP动词(GET,POST,PUT,DELETE)做为action操做URL资源
  • 过滤信息
    • limit:指定返回记录数量
    • offset:记录开始位置
    • direction:请求数据的方向,取值prev-上一页数据;next-下一页数据
    • page:第几页
    • per_page:每页条数
    • total_count:总记录数
    • total_pages:总页数,等于page时,表示当前是最后一页
    • sort:column1,column2排序字段
    • orderby:排序规则,desc或asc
    • q:搜索关键字(uri encode以后的)
  • 返回结果
    • GET:返回资源对象
    • POST:返回新生成的资源对象
    • PUT:返回完整的资源对象
    • DELETE:返回一个空文档
  • 速率限制
    • X-RateLimit-Limit: 每一个IP每一个时间窗口最大请求数
    • X-RateLimit-Remaining: 当前时间窗口剩余请求数
    • X-RateLimit-Reset: 下次更新时间窗口的时间(UNIX时间戳),达到下个时间窗口时,Remaining恢复为Limit

未遵循原则:git

  • Hypermedia API(HATEOAS),经过接口URL获取接口地址及帮助文档地址信息
  • 限制返回值的域,fields=id,subject,customer_name
  • 缓存,使用ETag和Last-Modified

参考:github

模块和版本说明

接口模块相互对立且有版本管理,模块名做为APP配置项进行存储,每一个模块的版本号version和endpoint在应用初始化时调用api模块信息接口(经过传递客户端应用名称和版本号获取各个API模块的endpoint和version)获取并存储web

  • 示例模块及最新版本号:
模块 模块用途 最新版本号
account 账户 v1
sms 短信 v1
open 一些开放接口,不须要公共参数 v1

公共参数

Headers

公共请求参数是指每一个接口均可能须要传递的参数,公共参数经过header传递。chrome

参数 是否必须 说明及header格式
app 全部接口必须 请求客户端应用标识,取值*-ios、*-android、*-pc、*-h5
header格式:
X-Co-App: $app
user_id App登陆后全部接口都传
Web经过session机制获取
用户标识
header格式:
Authorization: CoAPI base64(user_id:token)
token App登陆后全部接口都传
Web经过session机制获取
受权访问令牌
header格式:
Authorization: CoAPI base64(user_id:token)
  • Web应用经过cookies传递session id,user_id和token无需传递,接口会从session自动获取;json

  • 同一token值在App和Web各应用间通用(token即为session id);api

  • **APP修改user-agent,在原有user-agent的尾部添加$app/$versionNetType/$value。**如:浏览器

    • Dalvik/2.1.0 (Linux; U; Android 6.0.1; MI 4LTE MIUI/V7.5.3.0.MXGCNDE) $app-android/3.0.0 NetType/4G
    • Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/603.2.4 (KHTML, like Gecko) $app-ios/3.0.0 NetType/WIFI
  • app取值及释义示例

app取值 客户端名称【域名】
admin-pc 管理中心PC网页版【admin.url.com】
admin-h5 管理中心手机网页版【admin.url.com】
admin-ios 管理中心iOS版
admin-android 管理中心Android版

Cookies

  • **用于告知服务端是否支持Webp的Cookie:**cookie name是supportWebp,取值是1(支持)和0(不支持),未传递时服务端默认取值为0。
  • Webview植入Session的Cookie:

JWT & OAuth2

  • Json Web Token可用于替代session-cookie机制。但会存在一些问题,好比为过时token强制失效问题(用户修改了密码后,没法强制其余的终端token所有失效)。
  • OAuth2是受权其余开发者访问本身应用有限权限的受权机制。

权限

  • 权限分为
    • none:无需任何受权;
    • token:须要用户登陆受权,可经过header AuthorizationCookie CoSID传递;
    • admintoken:须要管理员登陆受权,可经过header AuthorizationCookie CoCPSID传递;
    • token || admintoken:用户登陆受权或管理员登陆受权均可以;
      图片
    • sign:须要签名,通常用于服务端内部相互调用,详见[ API HMAC-SHA1签名]({% post_url 2017-11-08-API-HMAC-SHA1-Sign %})。

状态码说明

正确
接口正常访问状况下,服务器返回2××的HTTP状态码。

HTTP状态码
200 OK - 表示已在响应中发出、资源更改为功(GET、PUT)
201 Created - 新资源被建立(POST)
204 No Content - 资源被删除(DELETE)

错误
当用户访问接口出错时,服务器会返回给一个合适的4××或者5××的HTTP状态码;以及一个application/json格式的消息体,消息体中包含错误码code和错误说明message。

  • 5××错误(500=<status code)为服务器或程序出错,客户端只须要提示“服务异常,请稍后重试”便可,该类错误不在每一个接口中列出。
  • 4××错误(400=<status code<500)为客户端的请求错误,须要根据具体的code作相应的提示和逻辑处理,message仅供开发时参考,不建议做为用户提示。
  • 部分错误示例:
code message HTTP状态码
InvalidToken 未登陆或受权过时,请登陆 401 Unauthorized
ValidationError 输入字段验证出错,缺乏字段或字段格式有误 422 Unprocessable Entity
AccountNotExist 帐户名不存在 404 Not Found
InvalidPassword 密码错误 401 Unauthorized
NotFound 请求的资源不存在 404 Not Found
AccountHasExist 帐户名已经存在 409 Conflict
MobileHasBinded 手机号已经绑定其余帐户 409 Conflict
InvalidSign 参数签名验证未经过 403 Forbidden
InvalidSMSCode 短信验证码错误 403 Forbidden
ExpiredSMSCode 过时的短信验证码 403 Forbidden
FrequencyLimit 发送过于频繁,请稍后再试 403 Forbidden
TimesExceeded 达到最大发送次数限制,请明天再试 403 Forbidden
VerifyTimesExceeded 达到最大校验次数,请明天再试 403 Forbidden
RateLimitExceeded 接口调用次数超过限制,请稍后再试 429 Too Many Requests
|    |
复制代码

InternalError |服务异常,请稍后再试 |500 Internal Server Error

参数传递

遵循RESTful规范,使用了GET, POST, PUT, DELETE共4种请求方法。

  1. GET:请求资源,返回资源对象
  2. POST:新建资源,返回新生成的资源对象
  3. PUT:新建/更新资源,返回完整的资源对象
  4. DELETE:删除资源,返回body为空
  • GET请求不容许有body, 全部参数经过拼接在URL以后传递,全部的请求参数都要进行遵循RFC 3986的URL Encode
  • DELETE删除单个资源时,资源标识经过path传递,批量删除时,经过在body中传递JSON。
  • POST, PUT请求,全部参数经过JSON传递,可选的请求参数,只传有值的,无值的不要传递,contentType为application/json。

4种请求动做中,GET、PUT、DELETE是幂等的;只有POST是非幂等的。幂等操做的特色是其任意屡次执行所产生的影响均与一次执行的影响相同。 是非幂等是判断接口使用POST仍是PUT的决定条件

注意: APP端获取json数据时,对于数值类型字段必须以数值类型转换,不管传递过来的值是否带引号。

图片
图片

速率限制Rate Limiting

  • 为了防止API被恶意调用,对API调用进行速率限制。
  • 速率限制为每IP每15分钟5000次(dev/qa为10W)调用(15分钟是一个时间窗口)。
  • 限制是针对全部接口模块一块儿计算的(Redis key为APIRL:{IP}),暂时没有特殊的模块或单个接口(将来可能有)。
  • 你能够经过每一个接口返回的HTTP headers了解当前速率限制的状况:
    • X-RateLimit-Limit: 每一个IP每一个时间窗口最大请求数
    • X-RateLimit-Remaining: 当前时间窗口剩余请求数
    • X-RateLimit-Reset: 下次更新时间窗口的时间(UNIX时间戳),达到下个时间窗口时,Remaining恢复为Limit
  • 超出速率限制,返回如下错误
    图片

安全注意事项

  • 用户登陆后用户的token;aliyun OSS的bucket、AccessKey ID与AccessKey secret;微视频的appid、sign、bucket;这些关键数据经过调用接口得到,须要在客户端以安全的方式存储。
  • 音频视频在APP内的存储,不容许被拷贝(即便越狱或root后拿走也没法使用)。

测试工具

推荐Chrome浏览器插件Postman做为接口测试工具, Postman下载地址

图片

文档生成工具

  • 生成的工具为apidoc,详细阅读官方文档:http://apidocjs.com

调用示例

  • 伪代码

    图片

  • PHP

    图片

API模块信息获取

  • App配置文件中仅存储api模块名,App初始化时请求获取api模块信息,获取各个api模块的信息(endpoint和version)。

接口文档参考示例

接口文档参考示例

相关文章
相关标签/搜索