40

Which one of these URIs would be more 'fit' for receiving POSTs (adding product(s))? Are there any best practices available or is it just personal preference?

/product/ (singular)

or

/products/ (plural)

Currently we use /products/?query=blah for searching and /product/{productId}/ for GETs PUTs & DELETEs of a single product.

cdeszaq
  • 30,869
  • 25
  • 117
  • 173
Arron S
  • 5,511
  • 7
  • 50
  • 57
  • Makes me think of collections in programming - item[4] or items[4]. – Peter Hedberg Mar 15 '13 at 20:28
  • The RESTful thing to do would be to use *the same* prefix for both collections and individual items. So you can POST or PUT to the same endpoint you can GET from. If you generate the ID on the server, the convention is to POST to the collection. If the ID is generated on the client, the convention is to POST to `/endpoint/{new_id}`. – Stijn de Witt Jun 26 '17 at 19:18

7 Answers7

28

Since POST is an "append" operation, it might be more Englishy to POST to /products, as you'd be appending a new product to the existing list of products.

As long as you've standardized on something within your API, I think that's good enough.

Since REST APIs should be hypertext-driven, the URI is relatively inconsequential anyway. Clients should be pulling URIs from returned documents and using those in subsequent requests; typically applications and people aren't going to need to guess or visually interpret URIs, since the application will be explicitly instructing clients what resources and URIs are available.

Rob Hruska
  • 118,520
  • 32
  • 167
  • 192
  • 1
    I would go further and say that using the plural form is definitely more natural than the singular. – Darrel Miller Nov 06 '09 at 21:26
  • 1
    If you're trying to create a readable URL slug, the singular can sometimes sound more natural (to human readers), e.g. "/product/15", read straight across is "Product 15", so you know you're dealing with a single, unique product. But then you're left with what to do with the "list of all products", putting it at /product (which sounds weird for a list) or /products (having to support two URIs for the same type of resource in your code). But in any case, readable URI slugs aren't typically the goal of a RESTfully designed application, since it's not usually for human consumption. – Rob Hruska Nov 06 '09 at 21:31
  • 1
    Re-reading my comment I realized that my intent was not very clear. I prefer to use plural for using a POST to append, but a non-plural for GET and PUT if the resource is a single entity. As I've stated in the past naming REST uris is as important as naming of classes and methods in OO design. i.e. It is not essential to use good names, but it really helps. – Darrel Miller Nov 07 '09 at 00:43
  • 12
    @Rob Hruska/@Darrel Miller: Acckk! Singular URLs add complexity and cause people to think about URLs in ways that don't map to their usage. URLs should not be viewed as a sentence but instead as a hierarchy; "/products/15" is the only one that should be considered, IMO. – MikeSchinkel Aug 15 '10 at 19:42
  • 2
    @Mike I think there are far more important things to debate than the grammatical correctness of URLs. Having said that, I reserve subresources of collection resources for subsetting. E.g. /Products/Obsolete or /Products/Hot, or Products/RecentlyViewed – Darrel Miller Aug 15 '10 at 20:21
  • @Mike also from an implementation perspective I would have a ProductsController that returns a list resource and a ProductController that takes a parameter and returns a single resource. Using the same "Products" segment to map to both controllers is not as natural for me. – Darrel Miller Aug 15 '10 at 20:22
  • @Darrel Miller: Fair points. FYI I've been reading your SO contributions for a few hours now and it makes me want to write a blog post to discuss points about REST for which you are hard-line. I can learn a lot from your experience but feel that some of your opinion is driven by what it appears you value (ease of maintaining complex internal systems) and what (it appears) you don't value (ease of adoption of less complex public APIs.) Unfortunately I just don't have time to do that blog post justice today or in the near future. :( – MikeSchinkel Aug 15 '10 at 21:56
  • One of the core ideas behind REST is that URLs represent resources and methods (GET, POST etc) represent actions that you can execute on those resources. So in that sense it is a bit weird to split up the URL space between plural and non-plural forms. I usually compare it with database tables. You can insert, create, update, delete the records in a table. Most people use plural names for tables. `SELECT * FROM products` would be equivalent to `GET /products`. – Stijn de Witt Jun 26 '17 at 19:23
11

Typically you use POST to create a resource when you don't know the identifier of the resource in advance, and PUT when you do. So you'd POST to /products, or PUT to /products/{new-id}.

With both of these you'll return 201 Created, and with the POST additionally return a Location header containing the URL of the newly created resource (assuming it was successfully created).

Greg Beech
  • 133,383
  • 43
  • 204
  • 250
4

In RESTful design, there are a few patterns around creating new resources. The pattern that you choose largely depends on who is responsible for choosing the URL for the newly created resource.

If the client is responsible for choosing the URL, then the client should PUT to the URL for the resource. In contrast, if the server is responsible for the URL for the resource then the client should POST to a "factory" resource. Typically the factory resource is the parent resource of the resource being created and is usually a collection which is pluralized.

So, in your case I would recommend using /products

Bryan Kyle
  • 13,361
  • 4
  • 40
  • 45
3

You POST or GET a single thing: a single PRODUCT.

Sometimes you GET with no specific product (or with query criteria). But you still say it in the singular.

You rarely work plural forms of names. If you have a collection (a Catalog of products), it's one Catalog.

S.Lott
  • 384,516
  • 81
  • 508
  • 779
  • 5
    Most recommendations I've seen for RESTful APIs say the opposite. It tends to make more sense to have /products and /products/{id} as the root is the collection (plural) and the one with an identifier is one item in that collection (selection from plural == singular). Products may be considered to be a catalog, but what if it's movies or comments? – Greg Beech Nov 06 '09 at 20:51
  • 2
    While true -- even StackOverflow uses the plural collections in their URL's -- I disagree. Singular makes more sense because a URI identifies a (singular) resource -- particularly for POST. – S.Lott Nov 06 '09 at 21:17
  • 3
    A URI does identify a resource. Sometimes a resource is a list of things. I see no reason to limit yourself to singular nouns. – Darrel Miller Nov 06 '09 at 21:29
  • 1
    Plurals aren't informative. That's why. You know the plural. Except in a few cases, it's the noun + "S". – S.Lott Nov 07 '09 at 00:37
1

I would only post to the singular /product. It's just too easy to mix up the two URL-s and get confused or make mistakes.

Marcus Leon
  • 55,199
  • 118
  • 297
  • 429
1

As many said, you can probably choose any style you like as long as you are consistent, however I'd like to point out some arguments on both sides; I'm personally biased towards singular

In favor of plural resource names:

  • simplicity of the URL scheme as you know the resource name is always at plural
  • many consider this convention similar to how databases tables are addressed and consider this an advantage
  • seems to be more widely adopted

In favor of singular resource names (this doesn't exclude plurals when working on multiple resources)

  • the URL scheme is more complex but you gain more expressivity
  • you always know when you are dealing with one or more resources based on the resource name, as opposed to check whether the resource has an additional Id path component
  • plural is sometimes harder for non-native speakers (when is not simply an "s")
  • the URL is longer
  • the "s" seems to be a redundant from a programmers' standpoint
  • is just awkward to consider the path parameter as a sub-resource of the collection as opposed to consider it for what it is: simply an ID of the resource it identifies
  • you can apply the filtering parameters only where they are needed (endpoint with plural resource name)
arpadf
  • 413
  • 3
  • 13
  • *"is just awkward to consider the path parameter as a sub-resource of the collection"* Why? If modeled correctly the URL expresses the hierarchy correctly. Personally I feel it can *become* awkward if *the same* resource is available at multiple places this way. But as long as there is only one 'owning' resource it makes perfect sense I think. `/books/of-men-and-mice/chapters/1`, or `orders/12543/orderlines/2`, or `places/EU/nl/Amsterdam`, etc. You should avoid mapping all relations this way, just 'owning' relations (where you set ON DELETE CASCADE in the DB usually). – Stijn de Witt Jun 27 '17 at 19:29
  • I'm no stranger of using the plural form, but examples like "/orders/1234" doesn't feel consistent to me: orders is plural while 1234 is a unique id and thus represent a singular object. In my view all orders and the order identified by id 1234 represent a single resource (set). Not two. You could argue that the single resource is a subset of the whole and I can accept that, but that is an artificial hierarchy. – arpadf Jun 29 '17 at 15:51
  • Well, my collection endpoint just returns an array. If I would define an array it would also be named in the plural form. E.g. `var books = [{title:'Of men and Mice'}, {..}, {..}]`. So it feels very consistent to me. – Stijn de Witt Jun 30 '17 at 23:07
  • That's fair, but would you name your variable "books" if you want to keep a reference to the book with title "One men and Mice" ? :) – arpadf Jul 18 '17 at 06:58
-2

you could use the same url for all of them and use the MessageContext to determine what type of action the caller of the web service wanted to perform. No language was specified but in Java you can do something like this.

WebServiceContext ws_ctx;
MessageContext ctx = ws_ctx.getMessageContext();
String action = (String)ctx.get(MessageContext.HTTP_REQUEST_METHOD);
if(action.equals("GET")
  // do something
else if(action.equals("POST")
  // do something

That way you can check the type of request that was sent to the web service and perform the appropriate action based upon the request method.

ChadNC
  • 2,528
  • 4
  • 25
  • 39
  • But which URI should he use, the singular or plural? – Rob Hruska Nov 06 '09 at 21:00
  • Whichever one he wants would work. I have several rest services that perform different operations based upon the request method. He could use the plural one or the singular one since the the operation that will be carried out will only be dependent upon the request method. So /product?query=blah could could handle the same request as /products?query=blah by making use of the request method. I hope that makes sense it's been a long day and my brain is tired. – ChadNC Nov 06 '09 at 21:41
  • Does not answer the question: singular versus plural. Many frameworks already support routing based on HTTP request methods (without having to hand-code). – Bruce Alderson Apr 26 '11 at 23:02