0

Lets consider the following flow to a RESTfull API:

    API root      
       |  
       v  
   user list     
       |  
       v  
  user details  
       |  
       v  
  user messages 

Suppose I have a client to consume the API, and I want to retrieve messages from a user with ID 42. From what I've been studying, my client is not supposed to know how to "build" urls, and it should follow the links given by the API.

How should I do to retrieve messages for the user with ID 42?

The only way I can think is "walk" the whole API from it's root to user messages, which doesn't look very pretty or efficient to me.

Eg:
1 - GET / and get the link to the list of users
2 - GET /user/?id=42 and get the link to details of the user with the ID 42
3 - GET /user/42/ and get the link to user 42 list of messages
4 - GET /user/42/messages/ and finally get the user messages

Did I get something wrong? Is this the right way according to Roy's Fielding paper? Or is it ok to just assume the messages url is "/user/{id}/messages/" and make the request directly?

Filipe
  • 3,398
  • 5
  • 21
  • 35
  • To keep it simple, the consumer of REST APIs should be provided the required APIs and their request/response structure. So that he is only concerned about how to render it or use the result in some or the other way. Moreover, for developers it's best practice top use `HATEOAS` concept while building REST APIs. – Madhusudan Joshi Jan 15 '14 at 11:56

3 Answers3

1

Use URL templates in your API root. Let the client consume the API root at runtime. It should look for a URL template named something like "user-messages" with the value of "/user/{userid}/messages/". Then let the client substitute "42" for "{userid}" in the template and do a GET on the resulting URL. You can add as many of these URL templates you want for all of the required, often used, use cases.

The difference between this solution and a "classic" web API is the late binding of URLs: the client reads the API root with its templates at runtime - as opposed to compiling the client with the knowledge of the URL templates.

Take a look at the HAL media type for some information about URL templates: http://stateless.co/hal_specification.html

I wrote this piece here some time ago to explain the benefits of hypermedia: http://soabits.blogspot.dk/2013/12/selling-benefits-of-hypermedia.html

Jørn Wildt
  • 4,274
  • 1
  • 21
  • 31
0

I believe what your real concern is should you go about implementing HATEOAS or not. Now as it's an integral part of REST specifications, it is recommended that each entity should have a link to it's child entity that it encompasses. In your case, API ROOT should show list of users with each "user" having a link (/root/users/{id}) to corresponding user's details. And each User details entity will contain a link to the list of "messages" (/root/users/{id}/messages) which, finally, inturn encompass the link to the actual message detail as well (/root/users/{id}/messages/{messageId}). This concept is extremely useful (and thus a part of the specifications) because the client doesn't need to know the url to where your entity is exposed. For example, if your users were on http://users.abc.com/rest/users/{id} but your messages were on http://messages.abc.com/rest/{userId}/messages/{messageId}, the user entity that encompasses the list of "messages" will already have link embedded to point to the right resource on a different server.

Now that being said, I haven't actually seen many REST implementations out there (I must admit I do not have TOO MUCH of an experience, but enough to give an opinion) where HATEOAS is being used widespread. In most cases the resources are almost always on the same server (environment) and the paths to resources are almost always relative to the root url.Thus, it doesn't make sense for the clients to parse out the embedded links from the object when they can generate one by themselves, especially when the client would like to provide access to a resource directly (View the message directly without getting the user entity provided you already know what the messageId is).

In the end, it all depends on how close do you want your REST implementations to that of specifications and what kind of clients are you going to have. My 2 cents would be: if you have time, implement REST with HATEOAS and feel proud about it :). There are libraries out there that will make this implementation (HATEOAS) somewhat transparent to you REST implementation (I believe spring has one, although not very mature. You can look at it here). If you are like me and don't have much time to go that route, I think you can continue with a normal REST implementation without HATEOAS and your clients will still be OK with it (or so I hope!)

Hope this helps!

shahshi15
  • 2,772
  • 2
  • 20
  • 24
0

I found this article about hacking urls: Avoid hackable URLs.
There is a very interesting discussion about the topic of this question in the comments section.

Filipe
  • 3,398
  • 5
  • 21
  • 35