一些基于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命名约定有点困惑。我们应该用复数还是单数来创建资源?决定的标准应该是什么?
当前回答
在这个问题上有很好的讨论点。在我的经验中,命名约定或者更确切地说,没有建立本地标准是许多长夜待命、头痛、危险的重构、可疑的部署、代码审查辩论等等的根本原因。特别是当它决定事情需要改变,因为一开始就没有充分考虑到。
一个实际问题跟踪了关于这个问题的讨论:
https://github.com/kubernetes/kubernetes/issues/18622
在这个问题上看到分歧是很有趣的。
我的观点是,当你考虑用户、帖子、订单、文档等常见实体时,你应该始终将它们视为实际实体,因为这是数据模型的基础。这里不应该混淆语法和模型实体,这将导致其他方面的混淆。然而,一切都是黑白的吗?确实很少这样。环境真的很重要。
当你想获取系统中用户的集合时,例如:
GET /user ->用户实体集合
GET /user/1 ->实体资源user:1 .单击“确定”
说我想要一个实体user的集合和说我想要users的集合都是有效的。
GET /users ->实体用户集合
GET /users/1 ->实体用户资源:1 .单击“确定”
从这里你可以说,从用户集合中,给我user /1。
但如果你分解用户的集合……它是一个实体的集合,其中每个实体都是一个User实体。
您不会说实体是用户,因为单个数据库表通常是用户的单个记录。但是,我们这里讨论的是基于rest的服务,而不是数据库ERM。
但这只适用于名词区分清楚的用户,而且很容易掌握。然而,当一个系统中有多种相互冲突的方法时,事情就会变得非常复杂。
事实上,这两种方法在大多数情况下都是有意义的,除了少数情况下英语就像意大利面条一样。它似乎是一种迫使我们做出许多决定的语言!
简单的事实是,无论你决定什么,你的意图要一致且合乎逻辑。
在我看来,在这里和那里混合是一个糟糕的方法!这会悄悄地引入一些可以完全避免的语义歧义。
看似单一的偏好:
https://www.haproxy.com/blog/using-haproxy-as-an-api-gateway-part-1/
这里也有类似的讨论:
https://softwareengineering.stackexchange.com/questions/245202/what-is-the-argument-for-singular-nouns-in-restful-api-resource-naming
这里最重要的常数是,这似乎确实取决于某种程度的团队/公司文化偏好,根据更大的公司指南中的细节,这两种方式都有许多优点和缺点。谷歌不一定是正确的,因为它是谷歌!这适用于任何指导方针。
不要把你的头埋在沙子里,不要把你的整个理解系统松散地建立在轶事例子和观点上。
你有必要为每件事建立坚实的推理吗?如果它适合你、你的团队和你的客户,并且对新手和经验丰富的开发者(如果你是在团队环境中)有意义,那就很好。
其他回答
路由中的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
我很惊讶地看到这么多人会追随复数名词的潮流。在实现单数到复数的转换时,是否注意到不规则复数名词?你喜欢疼痛吗?
看到 http://web2.uvcs.uvic.ca/elc/studyzone/330/grammar/irrplu.htm
不规则复数有很多种,但以下是最常见的:
形成复数形式的
Ends with -fe Change f to v then Add -s
knife knives
life lives
wife wives
Ends with -f Change f to v then Add -es
half halves
wolf wolves
loaf loaves
Ends with -o Add -es
potato potatoes
tomato tomatoes
volcano volcanoes
Ends with -us Change -us to -i
cactus cacti
nucleus nuclei
focus foci
Ends with -is Change -is to -es
analysis analyses
crisis crises
thesis theses
Ends with -on Change -on to -a
phenomenon phenomena
criterion criteria
ALL KINDS Change the vowel or Change the word or Add a different ending
man men
foot feet
child children
person people
tooth teeth
mouse mice
Unchanging Singular and plural are the same
sheep deer fish (sometimes)
请参阅谷歌的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 |
|--------------------------+---------------+-------------------+---------------+--------------|
如果你正在思考这个问题,这本书值得一读。
使用/resources的前提是它表示“所有”资源。如果执行GET /resources,则可能返回整个集合。通过发布到/resources,您将添加到集合中。
但是,单个资源在/resource上可用。如果执行GET /resource请求,则可能会出错,因为这个请求没有任何意义,而/resource/123则完全有意义。
使用/resource而不是/resources类似于使用文件系统和文件集合,/resource是包含单独的123,456个文件的“目录”。
没有对错之分,你喜欢什么就去做什么。
如何:
/resource/(不是/resource)
/resource/意味着它是一个包含“resource”的文件夹,它是一个“resource”文件夹。
而且我认为数据库表的命名惯例是相同的,例如,一个叫“user”的表就是一个“user”表,它包含了一个叫“user”的东西。