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

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

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


当前回答

我知道大多数人都在犹豫是用复数还是单数。这里没有解决的问题是,客户需要知道您使用的是哪一个,而且他们总是有可能犯错误。这就是我的建议的来源。

两者都怎么样?我的意思是,在整个API中使用单数形式,然后创建路由,将复数形式的请求转发到单数形式。例如:

GET  /resources     =     GET  /resource
GET  /resources/1   =     GET  /resource/1
POST /resources/1   =     POST /resource/1
...

你懂的。没有人是错的,最小的努力,客户总是会得到正确的。

其他回答

我不喜欢看到url的{id}部分与子资源重叠,因为id理论上可以是任何东西,而且会有歧义。它混合了不同的概念(标识符和子资源名)。

类似的问题经常出现在枚举常量或文件夹结构中,其中混合了不同的概念(例如,当您有Tigers、Lions和Cheetahs文件夹时,在同一级别上还有一个名为Animals的文件夹——这没有意义,因为其中一个是另一个的子集)。

一般来说,我认为端点的最后一个命名部分如果一次处理单个实体,应该是单数,如果处理一组实体,则应该是复数。

处理单个用户的端点:

GET  /user             -> Not allowed, 400
GET  /user/{id}        -> Returns user with given id
POST /user             -> Creates a new user
PUT  /user/{id}        -> Updates user with given id
DELETE /user/{id}      -> Deletes user with given id

然后有一个单独的资源用于对用户进行查询,通常返回一个列表:

GET /users             -> Lists all users, optionally filtered by way of parameters
GET /users/new?since=x -> Gets all users that are new since a specific time
GET /users/top?max=x   -> Gets top X active users

下面是一些处理特定用户的子资源的例子:

GET /user/{id}/friends -> Returns a list of friends of given user

交个朋友(多对多链接):

PUT /user/{id}/friend/{id}     -> Befriends two users
DELETE /user/{id}/friend/{id}  -> Unfriends two users
GET /user/{id}/friend/{id}     -> Gets status of friendship between two users

永远不会有任何歧义,资源的复数或单数命名都是在暗示用户他们可以期待什么(列表或对象)。对id没有限制,理论上可以让id为new的用户不与(潜在的未来)子资源名重叠。

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

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

GET /resources?Id=123

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

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

GET /resource?Id=123

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

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

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

请参阅谷歌的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   |
|--------------------------+---------------+-------------------+---------------+--------------|

如果你正在思考这个问题,这本书值得一读。

为了简单和一致性,我更喜欢使用单数形式。

例如,考虑以下url:

/客户/ 1

我将把客户视为客户集合,但是为了简单起见,集合部分被删除了。

另一个例子:

/设备/ 1

在这种情况下,equipment不是正确的复数形式。因此,为了简单起见,将其视为设备集合和删除集合,使其与客户案例一致。