架构师之路 — 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功能描述安全性幂等
GETSELECT获取一个(提供资源 ID)或多个(提供 Filter 条件)或全部资源,获取多个时使用 Query Parameters 进行过滤查询,使用 Pagination Parameters(e.g. limit、offset、page、sortby)进行分页查询。
POSTCREATE创建一个资源(杜绝一次创建多个资源)。XX
PUTUPDATE更新一个资源(提供完整的资源数据)。X
PATCHUPDATE更新一个资源(提供部分的资源数据)。X
DELETEDELETE删除一个资源。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功能描述
GETSELECT返回一个或多个资源的完整数据和 Status Code,返回一个时使用 ,返回多个时使用 [];若错误需要返回错误原因和正确提示。
POSTCREATE返回一个资源的完整数据和 Status Code;若错误需要返回错误原因和正确提示。
PUTUPDATE返回一个资源的完整数据和 Status Code;若错误需要返回错误原因和正确提示。
PATCHUPDATE返回一个资源的完整数据和 Status Code;若错误需要返回错误原因和正确提示。
DELETEDELETE仅返回 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 设计规范原则的主要内容,如果未能解决你的问题,请参考以下文章

架构师之路系列文章

架构师之路系列文章

架构师之路系列文章

我的全栈之路-Java架构师技术栈

[架构之路-4]:架构师 - 架构师的四大架构价值等级与架构师全面成长之路

架构师的技术升级之路