RESTFUL API 设计规范

Author Avatar
Moon 7月 27, 2017

RESTFUL API 设计规范

URI定义

  • 应该将API部署在专用域名之下
  • 不用大写
  • 用中杠(-)不用下杠(_)
  • 参数列表要 encode
  • URI中不应该出现动词,动词应该使用HTTP方法表示
  • URI中的名词表示资源集合,使用复数形式
  • 虽然/在URI中表达层级,但是避免为了追求REST导致层级过深,适当使用参数表示
    GET /comments/tid?tid=1&page=1

HTTP请求方法

请求方法 含义 备注
DELETE 删除资源
GET 查询资源
PATCH ?
POST 创建资源
PUT 更新资源

响应格式

  • 采用 JSON,不要使用 XML
  • 默认情况下 JSON 外层不需要嵌套大括号,API 需要支持JSONP跨域访问或者客户端无法访问 HTTP header 才需要加上嵌套大括号
  • 响应原则上采用dingo默认的返回格式
  • 正确的响应,包含 data 和 meta(仅当返回列表数据) 信息

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    {
    "data": {},
    "meta": {
    "pagination": {
    "per_page": 10,
    "total": 80,
    "total_page": 8
    }
    }
    }
  • 错误信息必须包含 statusmessage,2个部分

    1
    2
    3
    4
    {
    "status_code": 500,
    "message": "Internal Error"
    }
  • 默认情况下不要过滤 API 输出中的空格,并且要支持 gzip

常见HTTP响应码及含义

响应码 含义 备注
200 OK 对成功的 GET、PUT、PATCH 或 DELETE 操作进行响应。也可以被用在不创建新资源的 POST 操作上
201 Created 对创建新资源的POST操作进行响应。应该带着指向新资源地址的 Location header
204 No Content 对不会返回响应体的成功请求进行响应(比如 DELETE 请求)
304 Not Modified HTTP缓存 header 生效的时候用
400 Bad Request 请求异常,比如请求中的 body 无法解析
401 Unauthorized 没有进行认证或者认证非法。当 API 通过浏览器访问的时候,可以用来弹出一个认证对话框
403 Forbidden 当认证成功,但是认证过的用户没有访问资源的权限
404 Not Found 请求资源不存在
405 Method Not Allowed 所请求的HTTP方法不允许当前认证用户访问
410 Gone 表示当前请求的资源不再可用。当调用老版本API的时候很有用
415 Unsupported Media Type 如果请求中的内容类型是错误的
422 Unprocessable Entity 用来表示校验错误
429 Too Many Requests 由于请求频次达到上限而被拒绝访问
500 Internal Error 服务器内部错误

认证

RESTful API应该是无状态。这意味着对请求的认证不应该基于 cookie 或者 session。相反,每个请求应该带有一些认证凭证。

如果一直使用 SSL,认证凭证可以简单的使用随机生成的 access token,把其做为 HTTP Basic Auth 中 user name 字段的值传给 API。
这么做的好处是可以通过浏览器访问 - 如果浏览器从服务器收到 401 Unauthorized 状态码,它将会弹出一个对话框让人输出认证凭证。

当然,这种基于 token 来进行基本认证的方法只能当用户从 API 管理后台拷贝了一个 token 到自己的代码中才行。
如果搞不到 token,只能使用 OAuth 2 来把安全 token 传递给第三方。OAuth 2 使用 Bearer token,并且也是基于SSL来保证传输安全。

支持 JSONP 的 API 可能需要第三种方法来实现认证,因为 JSONP 的请求没法发送 HTTP Basic Auth 凭证或者 Bearer token。
这种情况下,可以使用一个额外的查询参数 access_token。
注意:使用查询参数来传递 token 存在一个固有的安全隐患,因为大多数 web 服务器会在服务器日志中保存查询参数。

不管怎么样,以上三种方法是用来在 API 之间传输 token 的方法。实际传输的 token 可以是一样的。