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

StackOverflow https://stackoverflow.com/questions/9169450

  •  26-04-2021
  •  | 
  •  

Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

I think that the second is more RESTful for the reason you state. The URL is a hierarchy. The user-id is not really part of the identification of the image, so why make it part of the identifier?

Make an /users/{user-id}/images resource that returns a list of URLs in the form /images/{image-id} to list the images that the user has uploaded, and you have the best of both worlds.

I think it all depends on semantics and intentions. It seems like you're talking about a protected resource, not a publicly available one. In this case your communication is more explicit and has the least amount of surprise when a more verbose format is used:

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

If it's a public resource then it can be identified by image-id only and then the shorter format would be more logical:

http://api.gallery.com/images/{image-id}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top