标签云

微信群

扫码加入我们

WeChat QR Code

I'm new to REST and I've observed that in some RESTful services they use different resource URI for update/get/delete and Create. Such asCreate - using /resources with POST method (observe plural) at some places using /resource (singular)Update - using /resource/123 with PUT methodGet - Using /resource/123 with GET methodI'm little bit confused about this URI naming convention. What should we use plural or singular for resource creation? What should be the criteria while deciding that?


Following this topic, I've collected a few examples of famous REST APIs in an article: inmensosofa.blogspot.com/2011/10/….

2019年07月23日26分59秒

The conclusion I reached after reading all the answers below: Always use singular because (a) it's consistent, (b) it maps directly to singular class and table names, (c) some plural nouns are irregular (unpredictable) in English

2019年07月24日26分59秒

See this answer for a link to singular table naming conventions, and there is another an article that mentions this exact issue Rest API Developer's Dilemma - thank you Sorter

2019年07月24日26分59秒

Great answer! But "default" directories in Windows have plural names. Like "Program Files", "Users", "Documents", "Videos" etc. Also I have encountered plural names in website urls much more often.

2019年07月24日26分59秒

the defacto convention pretty much most people and APIs out there take is keeping it plural at all times.Ids specify ONE resource cars/id

2019年07月24日26分59秒

"Neither way is right or wrong, go with what you like best.".Ah the famous line I hear so often and get sick and tired of hearing from people.Conventions matter and SHOULD be debated constructively amongst the community, that's where better solutions come about and good practices.When you are using both plural and singular for resource names in URIs, it complicates your code and the API because the user and the code behind the API has to account for that in routes and logic to differentiate single vs. plural whereas if you just stick with plural all the time you have no problems.

2019年07月24日26分59秒

TomaszPluskiewicz You are entirely right that clients do not care. As software developers we should care -- and for that I agree with WTF's comment that constructive debates about convention are valuable.

2019年07月24日26分59秒

So can someone just put a one word answer and have it accepted so I don't have to read this all (again).

2019年07月24日26分59秒

The difficulty or ease of this is due to not respecting HATEOS. It shouldn't matter whether it's plural or singular or anything else. You should respect the uri's sent from the server and not "build up" your uri's on the client. Then you have 0 mapping to do for your code.

2019年07月24日26分59秒

richard The client still has to do mapping. In HATEOS they would have to map to a name that represents the relationship (rel) to the URI construction. The rel, method (verb) and Content-Type then make up the resource media. This does not preclude the need for a good URI design. Even though the client might give precedence to the rel name the developers of the API still need a good human-readable standard for URI construction.

2019年07月24日26分59秒

BrianReindel agreed.

2019年07月24日26分59秒

I like the simplicity. The mapping also has the benefit of making documentation and tests on routes incredibly easy to write.

2019年07月23日26分59秒

This makes sense to me. However, we're a database-first shop, meaning we generate code and api entities from our database schema. And database standards tend to advocate singular table names, so we're going with that, but still under the same logic as this answer.

2019年07月24日26分59秒

This is the best answer as far as I'm concerned.I appreciate that API designers like the linguistic correctness of saying "get resource #123", but it's extra coding hassle when writing clients of the API as well as help documentation.(GET /api/people vs. GET /api/person/123? euuuchh.).... instead of thinking of it like "get resource #123", phrase it in your head like "get from the collection of resources that matches #123".

2019年07月24日26分59秒

Distinguishing plural/singular resources is not about linguistic correctness but about scale./employees/12 reads to me as the subset of the employees resource with id '12' (it could mean anything, for instance a saved search query on recently fired employees).If you read the above as the employee with id '12', how would you represent the subset? The only option is by making URI's more complex ore distinguishing collections containing objects from the objects themselves (i.e. singular vs plural).

2019年07月24日26分59秒

Choosing /employees/12 to represent a search query on recently fired employees (or any subset) would be bad design I think. If you want to represent subsets of any kind than I suggest to introduce them as resources (with proper names) in their own right.

2019年07月24日26分59秒

This has nothing to do with understandability for the clients. It's about addressing different things with different URLs. And being able to respond to all HTTP methods without being in conflict. You can have a resource that is a collection of items, and a resource that represents an item itself. For all I care the collections resource could be example.org/166316e2-e1and one particular item in that collection example.org/20d68348-ccc-001c4200de. The client should not construct URLs (that obviously doesn't scale, it isn't RESTful and that's what link relation types are for).

2019年07月24日26分59秒

If you don't think arbitrary URLs are pretty, feel free to identify a collection resource with a plural name and an individual item with a singular name. If you don't like english URLs and your natural language doesn't support that way of singualr/plural notation use something else to define it in your preferred language I suppose all languages enable you to somehow distinguish '/the-collection-of-bla/2321' versus 'bla/61' in writing. And each of those two different resources represent completely different results when sending GET/PUT/DELETE/POST/PATCH and others.

2019年07月24日26分59秒

Singular: In case, when part of your system is only one object (0-1, exists or not) e.g. users/1/avatar you can use singular form for label this single object (e.g. avatar) - more detailed example here: stackoverflow.com/a/38296217/860099 . BTW - very nice answer :)

2019年07月24日26分59秒

What about mapping to class and table names, which should be singular? (see other answer)

2019年07月24日26分59秒

WillSheppard - Class names are best in singular form and table names are best in plural form. For example Order is a good name for a class that deals with singular instances of objects referring to one order. OrderList is a name for a class that deals with multiple Order instances. Orders Table is a good name for a database table of many orders.

2019年07月23日26分59秒

I want to GET /orders but I only want /1

2019年07月24日26分59秒

Imho ORDER is just as good a name for a table.

2019年07月24日26分59秒

Singular names are always there /clothe/12/trouser/34 :)

2019年07月24日26分59秒

GertArnold the word clothe is a verb. Rest APIs generally stick to nouns when talking about resources and use verbs when describing actions. The singular form is clout, but is archaic and would likely be more suitably replaced by garment.

2019年07月24日26分59秒

Nice try. But it would be better as "accessLogEntries". :-)

2019年07月24日26分59秒

TomRussell why? The implications of this are important. I understand why you would use plural even when you're accessing a resource by an identifier, but for a many-to-one or one-to-one it's quite misleading. Consider an api that manages staff members for a multi-location company. Each staff member works at one location. GET /users/123/location should fetch the location that the user works at. Isn't GET /users/123/locations really misleading as a consumer?

2019年07月24日26分59秒

CarrieKendall I see your point. Since accessLog is modeled as an attribute, or value, rather than an entity it should be singular. If you're given to over-engineering, then a log entry would be an entity and you'd have /api/accessLogEntries?resource=123.

2019年07月24日26分59秒

Agreed, although, I think it does break convention of pluralize all the things. It's a tricky one. To me, it's important than an API be straight-forward ie documentation should compliment an already straight-forward implementation.

2019年07月24日26分59秒

I'm more of a programmer than a systems or database person so I like an API that tells a story rather than adheres to convention. The implications for automated documentation are real, though.

1970年01月01日00分03秒

Das Auto is way better than Die Autos. Also, English plural conventions are not consistent.

2019年07月24日26分59秒

The resource namespace is a matter of semantics, not implementation. So, using the DB tables analogy, is not very fortunate. Also when working with DB-s you are manipulating only tables, though of course you can affect the content (rows), but in REST there is no constraint to manipulate a single resource directly.

2019年07月24日26分59秒

I think this is a good analogy, but more important than deciding whether to go singular or plural is to be consistent with whichever you choose. You're not going to insert into Users and then select from User. Same rule should apply to REST resources - don't rename them depending what you're doing.

2019年07月24日26分59秒

Its not just table names, its also comparable to class names in OO (my class would be called Customer not Customers).

2019年07月24日26分59秒

In this case, semantic is too much important to simply accept "already defined" trends

2019年07月24日26分59秒

Seems like the plural form has been chosen because developers seem to assume that all resources are inherently part of some collection. However, the "accepted convention" seems to indicate that POST /users should create a single user, adding it to the collection. I disagree. POST /users should create a list of users (even if that is a list of 1), where as POST /user should create exactly one user. I see no reason why both plural and singular resource endpoints can't co-exist. They describe different behaviors, and shouldn't surprise anyone of their function.

2019年07月23日26分59秒

Isn't there a convention for specifying a resource id in the path? If so, it seems to be widely neglected. For instance, POST users/<id> would create a new user.

2019年07月24日26分59秒

TomRussell usually the server creates the id, so you wouldn't know the id to POST to yet.

2019年07月24日26分59秒

TomRussell, when the client determines (a kind of) id when creating a new resource, it is more common to use PUT /users/<id> instead of POST. POST has the interpretation "add this to the collection, and determine the id as part of that". PUT has the interpretation "update (or add) this resource with this id." See restcookbook.com/HTTP%20Methods/put-vs-post for a longer explanation of this principle.

2019年07月24日26分59秒

I don't understand the concern here. We are not supposed to change singular to plural programatically. Most of above plural forms are well known, and should not be a concern. If someone has poor English knowledge, he is going to spell any part of your variable incorrectly. Also, going by your logic, do you also recommend using singular forms to refer collections in source code as well?

2019年07月24日26分59秒

This addresses code that tries to "auto generate/mangle" endpoints (there are many opinionated libraries that assume plurality/singularity and attempt to map); however, this does to apply to explicitly chosen endpoint names any more than the picking the right word (regardless of how it's pluralized).

2019年07月24日26分59秒

POST /customer sounds like it's going to replace the one and only customer. This is my biggest grief with using singular resource names.

2019年07月24日26分59秒

andrew-t-finnell Isn't POST /customer supposed to do the very thing - insert a single customer?

2019年07月24日26分59秒

And your caches store everything twice. No thanks.

2019年07月24日26分59秒

If you are doing 302 redirects and your cache is storing everything twice, you have set up your cache wrong. Cache is not supposed to store 302 redirects.

2019年07月24日26分59秒

If you client always uses /resources and always get redirected to /resource, you've done it wrong. If someone else uses your API, they can either use the correct URL directly or be redirected (which works but is wrong) and it was you who opened the wrong way.

2019年07月24日26分59秒

Not sure by what you mean "wrong" - that's very subjective. It's not really wrong because it does work.

2019年07月24日26分59秒

This increases the maintenance cost, and the cost of understanding, and the amount of code required.

2019年07月24日26分59秒

It's not an argument for me since Postman offers collections, so you can save all resources as different collection items and test them individually. All you do is selecting resource from collection, you don't have to edit parameters/methods/etc everytime.

2019年07月24日26分59秒

Shouldn't this be split is /cart and /cart/item(s) anyway? Then you can address the whole cart (e.g. with a delete) or individual items?

2019年07月24日26分59秒

RobertGrant Wouldn't that be "/carts/items/123"? (eg. why "cart" and not "carts" is the rule is 'always plural'?)

2019年07月24日26分59秒

I'd argue that if production code is checked in that is able to perform a delete of everyone's cart items there are bigger issues than the naming convention. The likely hood they 'd remember an 's' over an ID is much less.

1970年01月01日00分03秒

Why are you mixing idioms here? You use the proper URI notation in the first paragraph and then switch to query parameters? Using query parameters to obtain a resource with an ID of 123 is wholly off base here.

2019年07月24日26分59秒

That was clearly a mistake. I have updated my answer now. Thanks for noticing it.

2019年07月24日26分59秒

After being downvoted again, I looked at what I wrote and I realized that the original post was correct. My point was exactly that if the user does the wrong thing, then using plural+singular will in fact give a better error message that using plural only.

2019年07月24日26分59秒

I still feel this is confusing the issue at hand. The idea of using plural is that it’s a collection. And the number on the end is an index into the collection. What if you GET /resource by itself? Using both plural and singular together is quite confusing. Saying /resources/123 says: Get my resource 123 in the resources bucket.

2019年07月24日26分59秒