原文链接: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
是OK
201
是创建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/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
如下👇
- Twitter: developer.twitter.com/en/docs/api...
- Facebook: developers.facebook.com/docs/refere...
- LinkedIn: developer.linkedin.com/apis
总结
在这篇文章中,我们学习了怎么设计有效的 URL
,来指明网络中独特的资源。