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

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

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


当前回答

尽管最流行的做法是使用复数的RESTful api,例如/api/resources/123,但有一个特殊的情况,我发现使用单数名称比使用复数名称更合适/更具表现力。这是一对一关系的例子。特别是如果目标项是一个值对象(在领域驱动设计范例中)。

让我们假设每个资源都有一个一对一的accessLog,它可以被建模为一个值对象,即不是实体,因此没有ID。它可以表示为/api/resources/123/accessLog。通常的动词(POST、PUT、DELETE、GET)可以恰当地表达意图,以及关系确实是一对一的事实。

其他回答

路由中的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

我也不认为这样做有什么意义,我认为这不是最好的URI设计。作为RESTful服务的用户,无论我访问的是列表还是列表中的特定资源,我都希望列表资源具有相同的名称。无论使用列表资源还是特定资源,都应该使用相同的标识符。

我的观点是:那些把时间从复数变成单数或者反过来的方法是在浪费CPU周期。我可能是个老派,但在我那个时代,类似的东西都是一样的。如何查找有关人员的方法?任何正则表达式都不能同时覆盖person和people而没有不良的副作用。

英语复数可以是非常随意的,它们不必要地妨碍代码。坚持一个命名约定。计算机语言应该是关于数学的清晰性,而不是关于模仿自然语言。

我更喜欢同时使用复数(/resources)和单数(/resource/{id}),因为我认为它更清楚地区分了处理资源集合和处理单个资源之间的逻辑。

作为一个重要的副作用,它还可以帮助防止某些人错误地使用API。例如,考虑这样一种情况,用户错误地试图通过将Id指定为如下参数来获取资源:

GET /resources?Id=123

在本例中,我们使用复数形式,服务器很可能会忽略Id参数并返回所有资源的列表。如果用户不小心,他会认为调用成功,并使用列表中的第一个资源。

另一方面,当使用单数形式时:

GET /resource?Id=123

服务器很可能会返回一个错误,因为Id没有以正确的方式指定,并且用户将不得不意识到某些事情是错误的。

对我来说,复数操作集合,而单数操作集合中的项。

集合允许使用GET / POST / DELETE方法

项允许GET / PUT / DELETE方法

例如

POST on /students将在学校增加一名新学生。

DELETE on /students将删除学校中的所有学生。

DELETE /student/123将从学校删除学生123。

这可能感觉不重要,但一些工程师有时会忘记id。如果路由总是复数并执行DELETE,可能会意外擦除数据。而在奇异点上缺少id则会返回404路由。

为了进一步扩展示例,如果API应该公开多所学校,那么如下所示

DELETE on /school/abc/students将删除学校abc中的所有学生。

选择正确的词语有时本身就是一个挑战,但我喜欢保持语汇的多样性。例如cart_items或cart/items感觉正确。相反,删除购物车,删除的是购物车对象本身,而不是购物车中的物品;)。