一些基于rest的服务使用不同的资源uri进行更新/获取/删除和创建。如
Create -在某些地方使用/resource(单数)使用POST方法使用/resources(复数) 更新-使用PUT方法使用/resource/123 Get -使用Get方法使用/resource/123
我对这个URI命名约定有点困惑。我们应该用复数还是单数来创建资源?决定的标准应该是什么?
一些基于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
其他回答
最重要的事情
当你在接口和代码中使用复数时,问问你自己,你的约定是如何处理这些词的:
/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也可以。
为什么不遵循数据库表名的流行趋势,通常采用单数形式?有过这样的经历,让我们重新使用。
表命名困境:单数和复数名称
尽管最流行的做法是使用复数的RESTful api,例如/api/resources/123,但有一个特殊的情况,我发现使用单数名称比使用复数名称更合适/更具表现力。这是一对一关系的例子。特别是如果目标项是一个值对象(在领域驱动设计范例中)。
让我们假设每个资源都有一个一对一的accessLog,它可以被建模为一个值对象,即不是实体,因此没有ID。它可以表示为/api/resources/123/accessLog。通常的动词(POST、PUT、DELETE、GET)可以恰当地表达意图,以及关系确实是一对一的事实。
对我来说,复数操作集合,而单数操作集合中的项。
集合允许使用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感觉正确。相反,删除购物车,删除的是购物车对象本身,而不是购物车中的物品;)。
我也不认为这样做有什么意义,我认为这不是最好的URI设计。作为RESTful服务的用户,无论我访问的是列表还是列表中的特定资源,我都希望列表资源具有相同的名称。无论使用列表资源还是特定资源,都应该使用相同的标识符。