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

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

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


当前回答

我很惊讶地看到这么多人会追随复数名词的潮流。在实现单数到复数的转换时,是否注意到不规则复数名词?你喜欢疼痛吗?

看到 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)

其他回答

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

集合允许使用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感觉正确。相反,删除购物车,删除的是购物车对象本身,而不是购物车中的物品;)。

复数

简单-所有url都以相同的前缀开头 逻辑——订单/获取订单的索引列表。 标准——被绝大多数公共和私有api广泛采用的标准。

例如:

GET /resources -返回资源项的列表

POST /resources -创建一个或多个资源项

PUT /resources—更新一个或多个资源项

PATCH /resources—部分更新一个或多个资源项

DELETE /resources -删除所有资源项

对于单个资源项:

GET /resources/:id -根据:id参数返回一个特定的资源项

POST /resources/:id—用指定的id创建一个资源项(需要验证)

PUT /resources/:id -更新一个特定的资源项

PATCH /resources/:id—部分更新特定的资源项

DELETE /resources/:id -删除指定的资源项

对于单数的提倡者,可以这样想:你会向某人要一份订单,并期待一件事,还是一份清单?那么,当您键入/订单时,为什么期望服务返回一列东西呢?

在这个问题上有很好的讨论点。在我的经验中,命名约定或者更确切地说,没有建立本地标准是许多长夜待命、头痛、危险的重构、可疑的部署、代码审查辩论等等的根本原因。特别是当它决定事情需要改变,因为一开始就没有充分考虑到。

一个实际问题跟踪了关于这个问题的讨论:

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

这里最重要的常数是,这似乎确实取决于某种程度的团队/公司文化偏好,根据更大的公司指南中的细节,这两种方式都有许多优点和缺点。谷歌不一定是正确的,因为它是谷歌!这适用于任何指导方针。

不要把你的头埋在沙子里,不要把你的整个理解系统松散地建立在轶事例子和观点上。

你有必要为每件事建立坚实的推理吗?如果它适合你、你的团队和你的客户,并且对新手和经验丰富的开发者(如果你是在团队环境中)有意义,那就很好。

我很惊讶地看到这么多人会追随复数名词的潮流。在实现单数到复数的转换时,是否注意到不规则复数名词?你喜欢疼痛吗?

看到 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)

最重要的事情

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

/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也可以。