Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resource and Action URI convention for REST

Tags:

rest

http

I am at a cross roads for developing some REST APIs and I have found no real discussion on the subject much less a firm defense of either.

It's my understand that with REST you have /<resource>/<action> as your URL

So, to disable a user you would have:

PUT /user/disable

Seems reasonable. However, we have the debate going on out more basic methods:

should it be:

POST /user  (creates a user *implicitly*)
POST /user/create (creates a user *explicitly*)

DELETE /user/:id
DELETE /user/:id/delete

The first seems to be what is considered "the standard" and the second is obviously much more clear in it's intent and is consistent with methods like /user/disable

Maybe this debate has raged elsewhere but I have not seen it. If you're 'religious' about this, now's your chance to pontificate

like image 478
Christian Bongiorno Avatar asked Aug 16 '12 01:08

Christian Bongiorno


People also ask

What is resource URI in REST API?

URI. REST APIs use Uniform Resource Identifiers (URIs) to address resources. REST API designers should create URIs that convey a REST API's resource model to the potential clients of the API.

Do all resources have unique URI in REST API?

RESTful clients use URLs to manipulate resources. Each resource must have its own unique URL. Some URL patterns have a collection path with a unique identifier appended.

What is the naming convention for REST endpoints?

REST APIs are typically structured in a hierarchy: for example, https://api.example.com/users/123/first-name will retrieve the first name of the user with ID number 123. The forward slash (“/”) character should be used to navigate this hierarchy, moving from general to specific when going from left to right in the URI.

How do you represent resources in REST?

REST uses various representations to represent a resource where Text, JSON, XML. The most popular representations of resources are XML and JSON.


2 Answers

Having /<resource>/<action> as your URL is not REST. REST uses HTTP verbs to determine actions to perform on a given resource, or on a collection of resources. That means:

  • Creating a resource is: POST /users
  • Reading a resource is: GET /users/<id>
  • Updating (replacing actually) a resource is: PUT /users/<id>
  • Deleting a resource is: DELETE /users/<id>

That's REST.

For all other methods, you can use other verbs like PATCH. Disabling a user could be:

PATCH /users/<id>/disable

It's not pure REST but it's ok.

Edit: If you want to be REST compliant, disabling a user means you want to change his state. In other words, you want to change one of its properties like a state flag. You can "patch" your resource:

PATCH /users/<id>?state=disabled

This is REST. You can also replace the resource by using PUT as described in the comments.

like image 145
William Durand Avatar answered Nov 01 '22 02:11

William Durand


@Christian Bongiorno

You are encoding actions in URIs which has nothing to do with REST. It's a clearest form of RPC.

You need to identify resource and perform actions on these resources with methods defined in underlying protocol you use(i.e. HTTP in your case). HTTP spec defines semantics for these methods so instead of encoding actions directly in URIs you must do following:

  • GET /users - returns list of users(each entry/item with its own link to particular user)
  • GET /users/:id - returns particular user
  • POST /users - creates new user under /users resource
  • POST /users/:id - edits user (alternatively PATCH method can be used here)
  • PUT /users/:id - replaces user
  • DELETE /users/:id - removes user

This is how you should think about actions. But this is not enough you need to use media format which provide support for such hypermedia controls as links(as minimum) in order to be able to describe these actions, for example see:

  • HAL - http://stateless.co/hal_specification.html
  • Collection.JSON - http://amundsen.com/media-types/collection/format/
  • Link relations registry - http://www.iana.org/assignments/link-relations/link-relations.xml

Some quick interaction examples:

***Request***
GET /users HTTP/1.1
Host: service.org
Accept: application/x+json

***Response***
HTTP/1.1 200 OK
Content-Type: application/x+json
Content-Length: ...

[{
  "name": "john",
  "links": {
    "self": "/users/1",
    "edit": "/users/1"
  }
}, {
  "name": "jane",
  "links": {
    "self": "/users/2",
    "edit": "/users/2"
  }
}]

***Request***
GET /users/2 HTTP/1.1
Host: service.org
Accept: application/x+json

***Response***
HTTP/1.1 200 OK
Content-Type: application/x+json
Content-Length: ...
{
  "name": "jane",
  "links": {
    "self": "/users/2",
    "edit": "/users/2"
  }
}

***Request***
DELETE /users/2 HTTP/1.1
Host: service.org

***Response***
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: ...

Resource was destroyed...

***Request***
POST /users/2 HTTP/1.1
Host: service.org
Content-Type: application/x+json
Content-Lenght: ...

{"status": "disabled"}

***Response***
HTTP/1.1 303 See Other
Location: /users/2
like image 45
ioseb Avatar answered Nov 01 '22 03:11

ioseb