一些基于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命名约定有点困惑。我们应该用复数还是单数来创建资源?决定的标准应该是什么?
当前回答
以下是Roy Fielding关于“基于网络的软件架构的架构风格和设计”的论文,这句话你可能会感兴趣:
资源是概念上的映射 到一组实体,而不是与中任何特定点的映射对应的实体 时间。
作为一个资源,映射到一组实体,对我来说,使用/product/作为访问一组产品的资源,而不是/products/本身,似乎不符合逻辑。如果需要特定的产品,则访问/products/1/。
作为进一步的参考,这个来源有一些关于资源命名约定的单词和例子:
https://restfulapi.net/resource-naming/
其他回答
我不喜欢看到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的用户不与(潜在的未来)子资源名重叠。
从API使用者的角度来看,端点应该是可预测的
在理想的情况下……
GET /resources should return a list of resources. GET /resource should return a 400 level status code. GET /resources/id/{resourceId} should return a collection with one resource. GET /resource/id/{resourceId} should return a resource object. POST /resources should batch create resources. POST /resource should create a resource. PUT /resource should update a resource object. PATCH /resource should update a resource by posting only the changed attributes. PATCH /resources should batch update resources posting only the changed attributes. DELETE /resources should delete all resources; just kidding: 400 status code DELETE /resource/id/{resourceId}
这种方法最灵活,功能最丰富,但开发起来也最耗时。因此,如果您很着急(软件开发总是这样),只需命名您的端点资源或复数形式的资源。我更喜欢单数形式,因为它让你可以选择内省和编程计算,因为不是所有的复数形式都以's'结尾。
说了这么多,不管出于什么原因,最常用的实践开发人员选择使用复数形式。这是我最终选择的路线,如果你看看流行的api,如github和twitter,这就是他们所做的。
决定的一些标准可以是:
我的时间限制是什么? 我将允许我的消费者做哪些操作? 请求和结果有效负载是什么样子的? 我是否希望能够在代码中使用反射并解析URI ?
所以这取决于你。无论你做什么都要坚持。
单数
方便 事物可以有不规则的复数名称。有时他们没有。 但是单数的名字总是存在的。
例如,CustomerAddress over CustomerAddresses
考虑这个相关的资源。
/order/12/orderdetail/12比/orders/12/orderdetails/4更具可读性和逻辑性。
数据库表
资源表示像数据库表这样的实体。 它应该有一个逻辑上的单数名称。 这是关于表名的答案。
类映射
类总是单数的。ORM工具生成的表与类名相同。随着越来越多的工具被使用,单数名称正成为一种标准。
阅读更多关于REST API开发者的困境
对于没有单一名称的事物
在裤子和太阳镜的例子中,它们似乎没有一个单一的对应。他们是众所周知的,他们似乎是单数的使用。就像一双鞋。考虑将类文件命名为Shoe或Shoes。在这里,这些名称的使用必须被视为一个单一的实体。你不会看到任何人买了一只鞋就把URL设为
/shoe/23
我们必须把鞋子看做一个单一的实体。
参考:Top 6 REST命名最佳实践
为了简单和一致性,我更喜欢使用单数形式。
例如,考虑以下url:
/客户/ 1
我将把客户视为客户集合,但是为了简单起见,集合部分被删除了。
另一个例子:
/设备/ 1
在这种情况下,equipment不是正确的复数形式。因此,为了简单起见,将其视为设备集合和删除集合,使其与客户案例一致。
我很惊讶地看到这么多人会追随复数名词的潮流。在实现单数到复数的转换时,是否注意到不规则复数名词?你喜欢疼痛吗?
看到 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)