怎么设计 REST 资源的 URL

原文链接:How to Design URL to REST Resource - 原文作者:Ramesh Fadatare
本文采用意译的方式

本文,我们将学习怎么设计 REST API 资源的 URL,并且了解设计一个 URL 资源的最佳实践。最后,我们将以真实的案例来实践学习。

怎么设计 REST 资源的 URL

我们通过案例来深入讨论。

基本上, URL 被分配给提取的资源以便来识别它。我们推荐使用下面的 URL 格式。

bash 复制代码
http(s)://{Domain name (:Port number)}/{A value indicating REST API}/{API version}/{path for identifying a resource}
bash 复制代码
http(s)://{Domain name indicating REST API(:Port number)}/{API version}/{path for identifying a resource}

典型的例子如下:

bash 复制代码
http://example.com/api/v1/members/M000000001
http://api.example.com/v1/members/M000000001

我们拆分 URL 并深入讨论下。

分配 URL,其指示 APIREST API

推荐 URL 域名或者路径包含 API 关键字,来清晰地指示改 URL 是为了 RESTful Web Service (REST API)的。典型,如下 URL

bash 复制代码
http://example.com/api/...
http://api.example.com/...

分配 URL,识别 API 版本

我们可以通过在 URL 上添加版本号来进行版本控制。在引入非向后兼容的更改时特别有用。

典型的,URL 中版本控制如下:

bash 复制代码
http://example.com/api/{API version}/{path for identifying a resource}
http://api.example.com/{API version}/{path for identifying a resource}

分配路径来识别资源

RESTful URIs 中不应该有动词在里面。该操作应该从 HTTP 方法(GET, POST, PUT, DELETE, etc.)推断出来,比如:

  • GET /orders - 获取订单列表
  • POST /orders - 新增一条订单

你应该避免如下写法:

  • /getOrders
  • /createOrder

使用相关的子资源:如果一个资源关联另外一个资源,你可以使用子资源:

  • /users/123/orders - 获取用户 ID123 的订单列表

使用 RESTful URL 设计的备忘录

1. 使用名词,而非动词

bash 复制代码
✅ /users
❌ /getUser

2. 频繁使用复数名词

bash 复制代码
✅ /books
❌ /book

3. 避免 CURD 术语

bash 复制代码
✅ GET /orders (该接口获取订单)
❌ /getAllOrders

4. 使用 ID 识别唯一资源

bash 复制代码
✅ /employees/45 (ID 为 45 的员工)
❌ /employees?employeeId=45

5.嵌套关系的子资源

bash 复制代码
✅ /departments/3/employees (部门 ID 为 3 的员工)
❌ /employeesInDepartment/3

6. 过滤,排序和分页时使用查询参数

bash 复制代码
✅ /books?author=Rowling&sort=title
❌ /booksByRowlingSortedByTitle

7. 实施版本控制(可选的,但是很有用)

bash 复制代码
✅ /v1/products
❌ /productsVersion1

8. 保持命名一致的约定

命名要么全使用驼峰式(/userGroups),要么全使用下划线格式(/user_groups),别混合着使用。

9. 坚持标准的 HTTP 方法

正确做法✅👇

  • POST 是创建
  • GET 是读取
  • PUT 是更新(或者创建)
  • DELETE 是删除

10. 使用 HTTP 状态码来指示结果

正确做法✅👇

  • 200OK
  • 201 是创建
  • 400 是错误的请求
  • 404 是资源找不到
  • 等等

案例学习 1

我们来到实战,设计 REST APIURL。以有一些员工的公司为例,我们编写一些 APIs/getAllEmployees 是一个代表员工列表的 API。其他的 API 如下:

  • /addNewEmployee
  • /updateEmployee
  • /deleteEmployee
  • /deleteAllEmployees
  • /promoteEmployee
  • /promoteAllEmployees

并且,还会有大量类似的其他 API 端用于不同的操作。其中的很多都是很冗余的操作。因此,当 API 的数量增加时,所有的 API 端点的维护变得越来越繁重。

这有什么问题?

之前说过,URL 应该只包含资源(名词),而不应该包含动作或者动词/addNewEmployee 含有资源 Employee,但是包含了动作 addNew

正确应该是怎样?

/companies 的端点是个很不错的例子,其不包含动作。但是,问题是,我们怎么告诉服务器要关于公司 companies 执行的资源操作呢,不管是否添加、删除或更新?

HTTP 方法 GET, POST, DELETE, PUT 派上用场,这些方法也称为动词。

API 端点,资源应该总是复数名词,如果我们想获取其中一个资源,我们可以通过 IDURL 传参。

  • GET 路径 /companies 表示获取公司的列表
  • GET 路径 /companies/34 表示获取 id34 的公司信息
  • DELETE 路径 /companies/34 表示删除 id34 的公司

在其他的用例中,资源下面又有资源,比如 Company 下有 Employees,那么。一些 API 端点的案例如下:

  • GET 路径 /companies/3/employees 表示 id3 的公司下的员工列表
  • GET 路径 /companies/3/employees/45 表示 id3 的公司下员工 id45 的信息
  • DELETE 路径 /companies/3/employees/45 表示删除 id3 的公司下 id45 的员工
  • POST 路径 /companies 表示创建一个新公司,并返回创建的公司信息

案例学习 2

我们来练习下怎么从域名信息中提取不同的资源编写 URL。我们以 HelpDesk 应用程序的消息和票证为例。

如果一个资源和另一个资源相关,RESTful 原则提供了不错的指导。信息可以以 /tickets 端点为逻辑展开,如下:

  • GET /tickets/12/messages - 获取 #12 票证的所有信息
  • GET /tickets/12/messsages/5 - 获取 #12 票证的 #5 信息
  • POST /tickets/12/messages - 在 #12 票证中创建信息
  • PUT /tickets/12/messages/5 - 更新 #12 票证的 #5 信息
  • PATCH /tickets/12/messages/5 - 更新 #12 票证的 #5 信息的部分内容
  • DELETE /tickets/12/messages/5 - 删除 #12 票证的 #5 信息

案例学习 3

下面是来自 twitter API 文档。

策划推文集合

  • GET collections/entries
  • GET collections/list
  • GET collections/show
  • POST collections/create
  • POST collections/destroy
  • POST collections/entries/add
  • POST collections/entries/curate
  • POST collections/entries/move
  • POST collections/entries/remove
  • POST collections/update

查看一些广泛使用的 API 以掌握窍门,并与队友完善 API 资源 URL。一些 APIs 如下👇

总结

在这篇文章中,我们学习了怎么设计有效的 URL,来指明网络中独特的资源。

相关推荐
救救孩子把6 分钟前
深入理解 Java 对象的内存布局
java
落落落sss8 分钟前
MybatisPlus
android·java·开发语言·spring·tomcat·rabbitmq·mybatis
万物皆字节14 分钟前
maven指定模块快速打包idea插件Quick Maven Package
java
夜雨翦春韭21 分钟前
【代码随想录Day30】贪心算法Part04
java·数据结构·算法·leetcode·贪心算法
我行我素,向往自由27 分钟前
速成java记录(上)
java·速成
twins352033 分钟前
解决Vue应用中遇到路由刷新后出现 404 错误
前端·javascript·vue.js
一直学习永不止步33 分钟前
LeetCode题练习与总结:H 指数--274
java·数据结构·算法·leetcode·数组·排序·计数排序
邵泽明33 分钟前
面试知识储备-多线程
java·面试·职场和发展
Yvemil71 小时前
MQ 架构设计原理与消息中间件详解(二)
开发语言·后端·ruby
程序员是干活的1 小时前
私家车开车回家过节会发生什么事情
java·开发语言·软件构建·1024程序员节