RESTful API Design – HTTP Verbs with Shared or Specific URLs

api-designrestweb-api

While creating a RESTful API, should I use HTTP Verbs on the same URL (when it's possible) or should I create an specific URL per action?

For example:

GET     /items      # Read all items
GET     /items/:id  # Read one item
POST    /items      # Create a new item
PUT     /items/:id  # Update one item
DELETE  /items/:id  # Delete one item

Or with specific URLs like:

GET     /items            # Read all items
GET     /item/:id         # Read one item
POST    /items/new        # Create a new item
PUT     /item/edit/:id    # Update one item
DELETE  /item/delete/:id  # Delete one item

Best Answer

In your latter scheme, you keep verbs in the URLs of your resources. This should be avoided as the HTTP verbs should be used for that purpose. Embrace the underlying protocol instead of ignoring, duplicating or overriding it.

Just look at DELETE /item/delete/:id, you place the same information twice in the same request. This is superfluous and should be avoided. Personally, I'd be confused with this. Does the API actually support DELETE requests? What if I place delete in the URL and use a different HTTP verb instead? Will it match anything? If so, which one will be chosen? As a client of a properly designed API, I shouldn't have to ask such questions.

Maybe you need it to somehow support clients that cannot issue DELETE or PUT requests. If that's the case, I'd pass this information in an HTTP header. Some APIs use an X-HTTP-Method-Override header for this specific purpose (which I think is quite ugly anyway). I certainly wouldn't place the verbs in the paths though.

Go for

GET     /items      # Read all items
GET     /items/:id  # Read one item
POST    /items      # Create a new item
PUT     /items/:id  # Update one item
DELETE  /items/:id  # Delete one item

What's important about the verbs is that they are already well-defined in the HTTP specification and staying in line with these rules allows you to use caches, proxies and possibly other tools external to your application that understand the semantics of HTTP but not your application semantics. Please note that the reason you should avoid having them in your URLs is not about RESTful APIs requiring readable URLs. It's about avoiding unnecessary ambiguity.

What's more, a RESTful API can map these verbs (or any subset thereof) to any set of application semantics, as long as it doesn't go against the HTTP specification. For example, it is perfectly possible to build a RESTful API that only uses GET requests if all operations that it allows are both safe and idempotent. The above mapping is just an example that fits your use case and is compliant with the spec. It doesn't necessarily have to be like this.

Please also mind that a truly RESTful API should never require a programmer to read extensive documentation of available URLs as long as you conform to the HATEOAS (Hypertext as the Engine of Application State) principle, which is one of the core assumptions of REST. The links can be utterly incomprehensible to humans as long as the client application can understand and use them to figure out possible application state transitions.

Related Topic