API 路由命名约定

fla*_*yte 10 rest api-design

我正在为一个私有项目开发 API(以及一个 SPA),我无法在两个路由命名约定之间做出决定。

假设我的数据库中有三个表:Users,ProductsOrders. 如果我希望用户能够订购产品,我应该遵循以下哪一项约定?

  1. POST /orders 与身体 { "product": 1 }
  2. POST /products/{id}/order

注意:在这两种情况下,user都将根据提供的访问令牌进行推断。

对我来说,上述驻留在接口的类型的两种解决方案之间的主要区别,以暴露到前端显影剂:我暴露路由资源(溶液1)或到操作被执行(溶液2)?

使用一种方法而不是另一种方法是否有实际的(不利的)优势,或者这只是个人品味的问题?

如果我错了,请纠正我,但根据我的理解,解决方案 1 是 REST(“创建此资源”),而解决方案 2 不是(“执行此操作”)。

此外,在解决方案 1 中,每条路由都会直接映射到我的数据库中的一个表,有些人说这是一个坏主意,因为外部开发人员可以根据 API 路由推断数据库的架构,但老实说,我不明白这是怎么回事。

fla*_*yte 9

TL; 博士

根据我的研究以及 GitHub 和 Instagram API 的端点,对于订购产品的用户来说,最有意义的是公开POST /users/123/orders {"product": 456}而不是POST /orders {"product": 456, "user": 123}. 这里的想法是考虑资源的上下文(如果有的话)。

来源

设计实用 RESTful API 的最佳实践

请注意,我们不需要在 URL 中使用“更新”动词短语,因为我们可以依靠 HTTP 动词来通知该操作。澄清一下,以下资源 URL 是多余的:

PUT http://api.example.com/customers/12345/update

通过请求中的 PUT 和“更新”,我们提供了混淆我们的服务消费者的机会!是“更新”资源吗?

更好的 RESTful API 的 10 个最佳实践

4. 使用子资源建立关系

如果一个资源与另一个资源相关,则使用子资源。

GET /cars/711/drivers/ Returns a list of drivers for car 711
GET /cars/711/drivers/4 Returns driver #4 for car 711
Run Code Online (Sandbox Code Playgroud)

GitHubInstagram API

GitHub 和 Instagram API 似乎也以这种方式工作,即在相关时使用资源的上下文

例如,如果您想使用 GitHub 的 API获取用户组织列表,您将使用GET /users/flawyte/orgs而不是GET /orgs {"username": "flawyte"}.

如果您想喜欢媒体,则与 Instagram 的 API 相同:POST /media/{media_id}/likes