Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hierarchical RESTful urls still preferred - in terms of added overhead - over flat urls?

Let's say I have a website where users can upload and show their pictures. A RESTful url to a single picture of that user would look like:

http://api.gallery.com/users/{user-id}/images/{image-id}

But the image-id itself is already unique, so this url would already be good enough to get it:

http://api.gallery.com/images/{image-id}

From the REST point of view, the first one would be favorable, but then I should verify, that this image is really from this user, because somebody could alter the url, changing the user-id to somebody else's. In the latter case I wouldn't need to add this check, meaning less processing time.

Is being RESTful in such a case still preferred?

like image 457
roberkules Avatar asked Feb 07 '12 00:02

roberkules


1 Answers

In short, both are preferred; Both may return the same "thing" but the "context" is different.

Let's take a look at your URLs:

  • /users: all users
  • /users/1: user #1
  • /users/1/images: all user #1's images
  • /users/1/images/1: user #1's image #1

All of the above URLs revolve around the "user" resource. It's "all users", "a user", "a user's images", etc.

  • /images: all images
  • /images/1: image #1

All of the above URLs revolve around the "image" resource. It's "all images" or "an image".

Now, on the surface, that distinction may seem relatively minor, but when building an API, the difference can have a large impact on how data is consumed.

For example, let's say that you want to get a list of all of user #1's images, which is preferred?

/users/1/images

or

/images?where=user.id eq 1

The first represents exactly what we want, is more constrained, and easier to understand, however, it doesn't mean we shouldn't also support the second form as the ability to query can be quite useful.

Now, what about if you want to get a list of images, with their associated user?

/users/???

or

/images?include=user

In this scenario, the first URL doesn't make much sense at all, as we are trying to get a list of images, not users, while, the second URL represents exactly what we want.

Now, with regards to security, that should ideally be done in a manner that is completely transparent to the consumer. A consumer should be able to say "I want all images." and only ever recieve all the images that they have access to. If they try to access a specific resource that they do not have access to, an appropriate HTTP error code should be returned.

like image 184
Michael Morton Avatar answered Nov 13 '22 12:11

Michael Morton