架构师之路 — API 经济 — RESTful API 设计规范原则
Posted 范桂飓
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了架构师之路 — API 经济 — RESTful API 设计规范原则相关的知识,希望对你有一定的参考价值。
目录
文章目录
URI
- 资源类 URI 命名使用全小写字母。
- 资源类 URI 命名尽量使用名词。
# 不应该:
POST /updateuser/userId
GET /getusers
# 应该:
PUT /users/userId
- 资源类 URI 命名尽量使用复数。
# 不应该:
GET /user
GET /User
# 应该:
GET /users
- 资源类 URI 命名使用 kebab-case(“-” 分隔)风格。
# 不应该:
/systemOrders
/system_orders
# 应该:
/system-orders
- 资源类 URI 命名尽量与关系型数据库表结构命名保持联系。
# URI
product-orders
# DB table
product_orders
- 参数使用 camelCase(驼峰)风格
# 不应该:
/system-orders/order_id
/system-orders/OrderId
# 应该:
/system-orders/orderId
- 在嵌套资源的 URI 中体现数据库关联关系。
# 从 shop 2 获取所有产品的列表。
GET /shops/2/products
# 获取产品 31 的详细信息,产品 31 属于 shop 2。
GET /shops/2/products/31
# 应该删除产品 31,它属于商店 2。
DELETE /shops/2/products/31
# 应该更新产品 31 的信息,只在 resource-URL 上使用 PUT,而不是集合。
PUT /shops/2/products/31
- URI 突出版本号。
- 大版本升级(Major):是那些肯定会破坏现有客户端应用的版本,比如在请求参数中添加一个新的必需参数,或改变返回结果中的字段。大版本体现在 URI 中。
- 小版本升级(Minor):当变更不会破坏客户端应用程序的运行时,可以使用小版本升级,例如添加可选字段或支持附加参数。这时候你可以为你的 API 增设小版本。小版本体现在 Header 中。
# 大版本
api.domain.com/v1/authors
# 小版本
x-api-version:v1.5.1
- URI 不具有表现层描述。
- URL 使用 “/” 划分层级,同时尽量避免使用多级 URI。
Request
Methods
使用 HTTP Request Methods 时,要注意方法的 “安全性” 和 “幂等性”:
- 安全性:指调用 HTTP Request Method,是否会导致资源状态变化。
- 幂等性:指多次调用 HTTP Request Method,只要输入不变,那么执行的结果也是不变的。
Method | 功能 | 描述 | 安全性 | 幂等 |
---|---|---|---|---|
GET | SELECT | 获取一个(提供资源 ID)或多个(提供 Filter 条件)或全部资源,获取多个时使用 Query Parameters 进行过滤查询,使用 Pagination Parameters(e.g. limit、offset、page、sortby)进行分页查询。 | √ | √ |
POST | CREATE | 创建一个资源(杜绝一次创建多个资源)。 | X | X |
PUT | UPDATE | 更新一个资源(提供完整的资源数据)。 | X | √ |
PATCH | UPDATE | 更新一个资源(提供部分的资源数据)。 | X | √ |
DELETE | DELETE | 删除一个资源。 | X | √ |
HEAD | 获取资源的元数据而非资源本身。此方法经常被用来测试超文本链接的有效性,可访问性,和最近的改变,例如:获取虚拟机镜像的属性信息。 | √ | √ | |
OPTIONS | 获取信息,关于资源的哪些属性是由客户端决定的。在跨域或使用代理请求时,通常会用到,OPTION 请求在于判定资源的选项或需求,或者服务器的能力。 | √ | √ |
Filter & Query Parameter
- 接受 limit 和 offset 参数。
GET /shops?offset=5&limit=5
- 接受 fields 参数。
GET /shops?fields=id,name,address,contact
- 接受 page_size(分页)参数。
Headers
- 只在 Header 中使用认证令牌。
Authorization: Bearer xxxxxx, Extra yyyyy
- 始终验证内容类型。
content-type: application/json
Request body
- 请求体 JSON 属性使用 camelCase(驼峰)风格。
# 不应该:
user_name: "Mohammad Faisal"
user_id: "1"
# 应该:
userName: "Mohammad Faisal"
userId: "1"
Response
Response Status Codes & Msg
Method | 功能 | 描述 |
---|---|---|
GET | SELECT | 返回一个或多个资源的完整数据和 Status Code,返回一个时使用 ,返回多个时使用 [];若错误需要返回错误原因和正确提示。 |
POST | CREATE | 返回一个资源的完整数据和 Status Code;若错误需要返回错误原因和正确提示。 |
PUT | UPDATE | 返回一个资源的完整数据和 Status Code;若错误需要返回错误原因和正确提示。 |
PATCH | UPDATE | 返回一个资源的完整数据和 Status Code;若错误需要返回错误原因和正确提示。 |
DELETE | DELETE | 仅返回 Status Code;若错误需要返回错误原因和正确提示。 |
HTTP Response Status Codes(状态码)就是一个三位数,分成五个类别:
-
1xx:相关信息(不常用)
-
2xx:操作成功
-
3xx:重定向(不常用)
-
4xx:客户端错误
-
5xx:服务器错误
Response body
- 请求体 JSON 属性使用 camelCase(驼峰)风格。
# 不应该:
user_name: "Mohammad Faisal"
user_id: "1"
# 应该:
userName: "Mohammad Faisal"
userId: "1"
- 在响应体中包括总资源数。
# 不应该:
users: [
...
]
# 应该:
users: [
...
],
total: 34
非资源类 URI 定义
现实情况中,总有一些场景(资源)是 HTTP Request Methods 所抽象不了的。
针对登陆验证场景,可以把用户在远程服务器的会话信息抽象为一个资源,这样的话,登陆动作其实就是在远程服务器增加了一个会话资源,反正,登出就是删除一个会话资源。
我们可以将此类型归纳为 “非资源类 URI”。因为这些通常不是 CRUD 操作,而是在系统中执行特定工作的函数,所以非资源类 URI 命名使用动词。
POST /alarm/245743/resend
POST /login
DELETE /logout
再比如,网上汇款场景,将汇款的动作定义为一种服务:
[POST] /smsService
"mobile":"13813888888","text":"hello world"
再比如,OpenStack 的虚拟机操作 start、stop、reboot、migration 等,将这些操作定义为一个 os-action 资源,然后通过不同在 Request Body 中使用不同的内容来进行区分:
[POST] /servers/uuid
"os-action": "start"
"os-action": "stop"
简而言之,如果某些动作是 HTTP Method 动词所表示不了的,就应该把这个动作做成一种资源。
以上是关于架构师之路 — API 经济 — RESTful API 设计规范原则的主要内容,如果未能解决你的问题,请参考以下文章