这个问题是关于最佳 REST API 设计以及我在嵌套资源和根级别集合之间进行选择时面临的问题。
为了演示这个概念,假设我有集合City
、Business
和Employees
。典型的 API 可以如下构建。假设 ABC、X7N 和 WWW 是键,例如 guid:
GET Api/City/ABC/Businesses (returns all Businesses in City ABC)
GET Api/City/ABC/Businesses/X7N (returns business X7N)
GET Api/City/ABC/Businesses/X7N/Employees (returns all employees at business X7N)
PUT Api/City/ABC/Businesses/X7N/Employees/WWW (updates employee WWW)
这看起来很干净,因为它遵循原始的域结构——企业在城市,员工在企业。单个项目可通过集合下的键访问(例如../Businesses
返回所有业务,同时../Businesses/X7N
返回单个业务)。
以下是 API 使用者需要能够执行的操作:
- 在一个城市获得企业
(GET Api/City/ABC/Businesses)
- 让企业的所有员工
(GET Api/City/ABC/Businesses/X7N/Employees)
- 更新个别员工信息
(PUT Api/City/ABC/Businesses/X7N/Employees/WWW)
第二次和第三次调用,虽然看起来在正确的位置,但使用了很多实际上不必要的参数。
- 要获得企业的员工,唯一需要的参数是企业的密钥 (
X7N
)。 - 要更新单个员工,唯一的参数需要它是员工的密钥 (
WWW
)
后端代码中的任何内容都不需要非关键信息来查找业务或更新员工。因此,相反,以下端点看起来更好:
GET Api/City/ABC/Businesses (returns all Businesses in City ABC)
GET Api/Businesses/X7N (returns business X7N)
GET Api/Businesses/X7N/Employees (returns all employees at business X7N)
PUT Api/Employees/WWW (updates employee WWW)
如您所见,我为企业和员工创建了一个新的根,即使从域的角度来看它们是一个子/子子集合。
这两种解决方案对我来说都不是很干净。
- 第一个示例要求提供不必要的信息,但其结构对消费者来说似乎是“自然的”(集合中的单个项目通过较低的叶子检索)
- 第二个示例只要求提供必要的信息,但不是以“自然”方式构建的——子集合可以通过根访问
- 添加新员工时,单个员工根将不起作用,因为我们需要知道将员工添加到哪个业务,这意味着调用至少必须驻留在业务根下,例如
POST Api/Businesses/X7N7/Employees
,这使得一切更加混乱.
有没有我没有想到的更清洁的第三种方式?