一些基于rest的服务使用不同的资源uri进行更新/获取/删除和创建。如

Create -在某些地方使用/resource(单数)使用POST方法使用/resources(复数) 更新-使用PUT方法使用/resource/123 Get -使用Get方法使用/resource/123

我对这个URI命名约定有点困惑。我们应该用复数还是单数来创建资源?决定的标准应该是什么?


当前回答

路由中的id应该被看作是列表的索引,命名也应该相应地进行。

numbers = [1, 2, 3]

numbers            GET /numbers
numbers[1]         GET /numbers/1
numbers.push(4)    POST /numbers
numbers[1] = 23    PUT /numbers/1

但是有些资源在它们的路由中不使用id,因为要么只有一个id,要么一个用户永远不能访问多个id,所以这些不是列表:

GET /dashboard
DELETE /session
POST /session
GET /users/{:id}/profile
PUT /users/{:id}/profile

其他回答

对我来说,最好有一个模式,你可以直接映射到代码(容易自动化),主要是因为代码是什么将在两端。

GET  /orders          <---> orders 
POST /orders          <---> orders.push(data)
GET  /orders/1        <---> orders[1]
PUT  /orders/1        <---> orders[1] = data
GET  /orders/1/lines  <---> orders[1].lines
POST /orders/1/lines  <---> orders[1].lines.push(data) 

从API使用者的角度来看,端点应该是可预测的

在理想的情况下……

GET /resources should return a list of resources. GET /resource should return a 400 level status code. GET /resources/id/{resourceId} should return a collection with one resource. GET /resource/id/{resourceId} should return a resource object. POST /resources should batch create resources. POST /resource should create a resource. PUT /resource should update a resource object. PATCH /resource should update a resource by posting only the changed attributes. PATCH /resources should batch update resources posting only the changed attributes. DELETE /resources should delete all resources; just kidding: 400 status code DELETE /resource/id/{resourceId}

这种方法最灵活,功能最丰富,但开发起来也最耗时。因此,如果您很着急(软件开发总是这样),只需命名您的端点资源或复数形式的资源。我更喜欢单数形式,因为它让你可以选择内省和编程计算,因为不是所有的复数形式都以's'结尾。

说了这么多,不管出于什么原因,最常用的实践开发人员选择使用复数形式。这是我最终选择的路线,如果你看看流行的api,如github和twitter,这就是他们所做的。

决定的一些标准可以是:

我的时间限制是什么? 我将允许我的消费者做哪些操作? 请求和结果有效负载是什么样子的? 我是否希望能够在代码中使用反射并解析URI ?

所以这取决于你。无论你做什么都要坚持。

请参阅谷歌的API设计指南:资源名称以了解另一种命名资源的方法。

该指南要求集合以复数形式命名。

|--------------------------+---------------+-------------------+---------------+--------------|
| API Service Name         | Collection ID | Resource ID       | Collection ID | Resource ID  |
|--------------------------+---------------+-------------------+---------------+--------------|
| //mail.googleapis.com    | /users        | /name@example.com | /settings     | /customFrom  |
| //storage.googleapis.com | /buckets      | /bucket-id        | /objects      | /object-id   |
|--------------------------+---------------+-------------------+---------------+--------------|

如果你正在思考这个问题,这本书值得一读。

路由中的id应该被看作是列表的索引,命名也应该相应地进行。

numbers = [1, 2, 3]

numbers            GET /numbers
numbers[1]         GET /numbers/1
numbers.push(4)    POST /numbers
numbers[1] = 23    PUT /numbers/1

但是有些资源在它们的路由中不使用id,因为要么只有一个id,要么一个用户永远不能访问多个id,所以这些不是列表:

GET /dashboard
DELETE /session
POST /session
GET /users/{:id}/profile
PUT /users/{:id}/profile

最重要的事情

当你在接口和代码中使用复数时,问问你自己,你的约定是如何处理这些词的:

/pants, /eye-glasses——是单数还是复数? /radii -你知道它的唯一路径是/radius还是/radix吗? /index -你知道它的复数路径是/indexes或/indexes或/indexes吗?

理想情况下,约定的规模应该没有不规则性。英语复数就不会这样,因为

它们也有例外,比如某物被称为复数形式,以及 没有简单的算法可以从一个词的单数中得到一个词的复数,从复数中得到一个词的单数,或者判断一个未知名词是单数还是复数。

这也有缺点。我脑海中最突出的是:

The nouns whose singular and plural forms are the same will force your code to handle the case where the "plural" endpoint and the "singular" endpoint have the same path anyway. Your users/developers have to be proficient with English enough to know the correct singulars and plurals for nouns. In an increasingly internationalized world, this can cause non-negligible frustration and overhead. It singlehandedly turns "I know /foo/{{id}}, what's the path to get all foo?" into a natural language problem instead of a "just drop the last path part" problem.

与此同时,一些人类语言甚至没有名词的单数形式和复数形式。他们还行。你的API也可以。