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

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

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


当前回答

这两种表示都很有用。在相当长的一段时间里,我为了方便而使用单数,屈折变化可能会很困难。根据我在开发严格的单一REST api方面的经验,使用端点的开发人员对结果可能是什么形状缺乏确定性。我现在更倾向于使用最能描述反应形式的术语。

如果您的所有资源都是顶级的,那么您可以使用单一表示。避免变化是一个巨大的胜利。

如果您正在使用任何类型的深度链接来表示关系上的查询,那么使用您的API编写程序的开发人员可以通过使用更严格的约定来获得帮助。

我的习惯是,URI中的每一层深度都描述了与父资源的交互,而完整的URI应该隐式地描述正在检索的内容。

假设我们有以下模型。

interface User {
    <string>id;
    <Friend[]>friends;
    <Manager>user;
}

interface Friend {
    <string>id;
    <User>user;
    ...<<friendship specific props>>
}

如果我需要提供一个资源,允许客户端获得特定用户的特定朋友的管理器,它可能看起来像这样:

GET /用户/ {id} /朋友/ {friendId} /经理

下面是更多的例子:

GET /users - list the user resources in the global users collection POST /users - create a new user in the global users collection GET /users/{id} - retrieve a specific user from the global users collection GET /users/{id}/manager - get the manager of a specific user GET /users/{id}/friends - get the list of friends of a user GET /users/{id}/friends/{friendId} - get a specific friend of a user LINK /users/{id}/friends - add a friend association to this user UNLINK /users/{id}/friends - remove a friend association from this user

注意每个级别是如何映射到一个可以被操作的父级的。为同一个对象使用不同的父对象是违反直觉的。在GET /resource/123处检索资源时,没有指示应该在POST /resources处创建新资源

其他回答

使用单数,并利用英语惯例,如:“商业目录”。

很多东西都是这样读的:“书柜”、“狗窝”、“美术馆”、“电影节”、“汽车场”等等。

这方便地从左到右匹配url路径。左边的项目类型。在右侧设置类型。

GET /users真的获取过一组用户吗?不是很经常。它获取一组存根,其中包含一个密钥,也许还有一个用户名。所以它不是/users。它是一个用户索引,或者你可以称之为“用户索引”。为什么不这么叫呢?它是/user/index。由于我们已经命名了set类型,我们可以有多个类型来显示用户的不同投影,而无需求助于查询参数,例如user/phone-list或/user/mail -list。

那么用户300呢?仍然是/user/300。

GET /user/index
GET /user/{id}

POST /user
PUT /user/{id}

DELETE /user/{id}

最后,HTTP对单个请求只能有一个响应。路径总是指一个单数的东西。

对于命名惯例,通常可以安全地说“只选择一个并坚持使用它”,这是有道理的。

然而,在不得不向许多人解释REST之后,将端点表示为文件系统上的路径是最具表现力的方法。 它是无状态的(文件存在或不存在),分层的,简单的,熟悉的-您已经知道如何访问静态文件,无论是本地还是通过http。

在这种情况下,语言规则只能让你达到以下效果:

一个目录可以包含多个文件和/或子目录,因此它的名称应该是复数形式。

但我喜欢妳 不过,另一方面,这是您的目录,如果您愿意,您可以将其命名为“一个资源或多个资源”。这不是真正重要的事情。

重要的是,如果您将一个名为“123”的文件放在名为“resourceS”的目录下(结果是/resourceS/123),那么您就不能期望通过/resource/123访问它。

不要试图让它变得比原来更聪明——根据你当前访问的资源数量从复数变成单数对某些人来说可能是美观的,但这并不是有效的,在一个等级系统中也没有意义。

注意:技术上,你可以创建“符号链接”,这样/resources/123也可以通过/resource/123访问,但前者仍然必须存在!

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

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

以下是Roy Fielding关于“基于网络的软件架构的架构风格和设计”的论文,这句话你可能会感兴趣:

资源是概念上的映射 到一组实体,而不是与中任何特定点的映射对应的实体 时间。

作为一个资源,映射到一组实体,对我来说,使用/product/作为访问一组产品的资源,而不是/products/本身,似乎不符合逻辑。如果需要特定的产品,则访问/products/1/。

作为进一步的参考,这个来源有一些关于资源命名约定的单词和例子:

https://restfulapi.net/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)