URI Construction for REST API and Use of Verbs as Resources

resturi

I have two questions.

1) I have a issue of understanding the correct URL construction for a REST API. For example,

https://api.context.io/lite/users/id/email_accounts/label/folders/folder/messages/message_id

Here as you can see the folder comes under folders resource and message_id comes under messages. Is it necessary to show the parent resource or collection. Will it be wrong to have a URL such as this?

https://api.context.io/lite/userid/folderid/message_id

Here, the userid, folderid and message_id maybe would indicate as integers or some other value. Of course with the values the URL doesn't make sense, but does it matter in m2m transaction? What is the best way to construct the URL?

2) Is it ok to have 'verbs' in the URL? I have seen the following urls which has verbs such as 'move', 'send' in the URL. Is that correct? If it is wrong, should we do everything such as 'search' using parameters only?

POST https://outlook.office365.com/api/v1.0/me/messages/{message_id}/move
POST https://www.googleapis.com/gmail/v1/users/userId/messages/send

Please share your thoughts. I read lots of articles on these. Yet it seems to be more of a personal choose rather than an Industry standard. What would Dr. Fielding would recommend?

Thanks in advance.

Best Answer

1) It's typically best to be explicit about the display of your rested resources. Thus, it makes sense to follow the collection/:id/sub-collection/:id paradigm with your API.

2) It's considered an anti-pattern in the REST world to use anything other than nouns for your collections in your URIs. That's because REST best practices expect your "verbiage" to come in the form of HTTP verbs, and not something you've decided to declare on your own. This isn't a REST constraint by any means, but it's considered the best possible implementation, and allows developers to keep things consistent.

The HTTP verbs GET POST PUT and DELETE are suitable for any need your program may have. Oftentimes, if you feel you "need more verbs" in order to successfully implement a feature, it really means you need to expand your thinking of the resource on which that call is being made.

For example: if I wanted to login a user, my first thought may be to put that action on the User class via a User#login method. That'd get pretty weird, though, right? We're using a verb, and we now know that's a REST anti-pattern.

Instead, what if we created an associated Session class? Now we can conveniently call Session#create on a new instance of the model (that's associated with User) and stay RESTful as hell!

I really hope this helps. Remember: when in doubt, keep in mind that no matter what you're doing, the community has found a way to keep things RESTful, as there are some BIG OL' applications out there that adhere pretty strictly to the rules of REST.

UPDATE

Why not use a class method? I haven't seen your code, but I'm assuming you're using something like rails for your api.

You could do the following:

///items/index.html.erb
<% form_tag items_path, method: :get do %>
<p>
  <%= text_field_tag :search, params[:search] %>
  <%= submit_tag "Search", name: nil %>
</p>
<% end %>

///items_controller.rb
def index
  @items = Item.search(params[:search])
end

///models/item.rb
def self.search(search)
  if search
    find(:all, conditions: ['name LIKE ?', "%#{search}%"])
  else
    find(:all)
  end
end

This is obviously fairly vague object naming, but I think you'll get the idea. That way, you're always using a GET HTTP verb, and doing it in a restful manner. The other option, yes, is to use query params. This helps you avoid doing that.

Related Topic