本文转载自 RESTful 资源命名最佳实践
RESTful 资源命名最佳实践
2019-09-20 2021-05-07 7
6k 5 分钟
在 Rest 中,数据的呈现方式叫做资源 (Resource)。拥有强大而一致的 REST 资源命名策略,是最好的设计决策。
一个资源可以是单个的也可以是一个集合。比如 customers 是一个集合,而 customer 是单个资源。我们可以定义 customers 这个集合的资源的 URI 是 /customers
, 而单个 customer 资源的 URI 是 /customers/{customerId}
。
资源也可以包含子集合的资源。比如,使用 /customers/{customerId}/accounts
来表示某个 customer 下的 account 集合资源。同样的,对于 account 集合资源下的单个 account 我们可以定义成这样:/customers/{customerId}/accounts/{accountId}
REST API 使用统一资源标识符(URI)来寻址资源。REST API 设计者应该创建 URI,将 REST API 的资源模型传达给潜在的客户端开发人员。当资源命名良好时,API 直观且易于使用。如果做得不好,那么相同的 API 会感觉难以使用和理解。
使用名词来表示资源
RESTful URI 应该引用作为事物(名词)的资源而不是引用动作(动词),因为名词具有动词不具有的属性 - 类似于具有属性的资源。资源的一些示例是:
- 系统的用户
- 用户账户 (银行的场景):
- 网络设备
它们的资源 URI 可以被设计成下面这样:
1 | http://api.example.com/device-management/managed-devices |
为了更好的说明我们把资源原型分为四个种类 (document,collection,store 以及 controller), 你应该总是把资源放到其中一个原型中,并且遵守它的统一命名。
document
文档资源是一种类似于对象实例或数据库记录的单一概念 (比如 mysql 中的一行记录,Mongodb 中的 document), 在 REST 中,你可以将其视为资源集合中的单个资源。文档的状态表示通常包括具有值的字段和指向其他相关资源的链接。
使用单数名称表示文档资源原型
1 | http://api.example.com/device-management/managed-devices/{device-id} |
collection
集合资源是服务端管理的资源目录。客户可以建议将新资源添加到集合中。但是,要由集合选择是否创建新资源。集合资源选择它想要包含的内容,并决定每个包含的资源的 URI。
使用复数名称表示集合资源原型
1 | http://api.example.com/device-management/managed-devices |
store
store 是客户端管理的资源库 ,store 资源允许 API 客户端放入资源,取出资源,并决定何时删除它们。store 永远不会生成新的 URI。相反,每个存储的资源都有一个客户端在最初放入存储时选择的 URI。
使用复数名称表示 store 资源原型
1 | http://api.example.com/cart-management/users/{id}/carts |
controller
controller 资源有点像程序的概念,controller 资源就像可执行函数,带有参数和返回值;输入和输出。
使用动词表示 controller 原型
1 | // 查看用户的信用卡 |
这里的 controller 为什么要用动词呢?其实大家可以想象下 Spring 中 Controller 做了什么事情,它调用了 service 组合成各个业务逻辑,将数据组合起来之后进行返回.
一致性
使用一致的资源命名约定和 URI 格式,以最小化和最大可读性和可维护性。你可以实现以下设计提示以实现一致性:
使用正斜杠(/)表示层次关系
正斜杠(/)字符用于 URI 的路径部分,以指示资源之间的层次关系
1 | http://api.example.com/device-management |
不要在 URI 中使用尾部正斜杠(/)
作为 URI 路径中的最后一个字符,正斜杠(/)不会添加语义值,并可能导致混淆。最好完全放弃它们
1 | http://api.example.com/device-management/managed-devices/ |
使用连字符( - )来提高 URI 的可读性
要使你的 URI 易于扫描和解释,请使用连字符( - )字符来提高长路径段中名称的可读性。
1 | // 更好可读性 |
不用使用下滑线 _
可以使用下划线代替连字符作为分隔符 - 但是根据应用程序的字体,下划线 _ 字符可能会在某些浏览器或屏幕中被部分遮挡或完全隐藏。为避免这种混淆,请使用连字符 - 而不是下划线 _。
1 | // 更具可读性 |
在 URI 中使用小写字母
方便时,URI 路径中应始终首选小写字母。
RFC 3986 将 URI 定义为区分大小写,但协议和 host 除外
1 | // 1 |
在上面的例子中,1 和 2 是相同的,但 3 不是,因为它使用大写字母的 My-Folder。
不要使用文件扩展名
文件扩展名看起来很糟糕,不会增加任何优势。删除它们也会减少 URI 的长度。没理由保留它们。除了上述原因,如果你想使用文件扩展突出显示 API 的媒体类型,那么你应该依赖于通过 Content-Type 标头传达的媒体类型来确定如何处理正文的内容。
1 | // 不要这样用 |
切勿在 URI 中使用 CRUD 函数名称
URI 不应用于指示执行 CRUD 功能。URI 应该用于唯一标识资源,而不是对它们的任何操作。应使用 HTTP 请求方法来指示执行哪个 CRUD 功能。
1 | // 获取所有设备 |
使用查询组件过滤 URI 集合
很多时候,你会遇到需要根据某些特定资源属性对需要排序,过滤或限制的资源集合的要求。为此,不要创建新的 API - 而是在资源集合 API 中启用排序,过滤和分页功能,并将输入参数作为查询参数传递
1 | http://api.example.com/device-management/managed-devices |