原文链接: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,其指示 API 为 REST 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 - 获取用户
ID为123的订单列表
使用 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 状态码来指示结果
正确做法✅👇
200是OK201是创建400是错误的请求404是资源找不到- 等等
案例学习 1
我们来到实战,设计 REST API 的 URL。以有一些员工的公司为例,我们编写一些 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 端点,资源应该总是复数名词,如果我们想获取其中一个资源,我们可以通过 ID 在 URL 传参。
GET路径/companies表示获取公司的列表GET路径/companies/34表示获取id为34的公司信息DELETE路径/companies/34表示删除id为34的公司
在其他的用例中,资源下面又有资源,比如 Company 下有 Employees,那么。一些 API 端点的案例如下:
GET路径/companies/3/employees表示id为3的公司下的员工列表GET路径/companies/3/employees/45表示id为3的公司下员工id为45的信息DELETE路径/companies/3/employees/45表示删除id为3的公司下id为45的员工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/entriesGET collections/listGET collections/showPOST collections/createPOST collections/destroyPOST collections/entries/addPOST collections/entries/curatePOST collections/entries/movePOST collections/entries/removePOST collections/update
查看一些广泛使用的 API 以掌握窍门,并与队友完善 API 资源 URL。一些 APIs 如下👇
- Twitter: developer.twitter.com/en/docs/api...
- Facebook: developers.facebook.com/docs/refere...
- LinkedIn: developer.linkedin.com/apis
总结
在这篇文章中,我们学习了怎么设计有效的 URL,来指明网络中独特的资源。