Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RESTful api and related resources

Tags:

rest

php

laravel

I'm developing my first RESTful api, which (unfortunately) is being done on an already existing system and the idea is to allow third-parties to access this system.

Everything was fine until I realised that I have multiple ways to access the same resources. I will try to explain it using one of the parts of the system. The system has been built using Laravel 5.8 and has, among others, the following database tables:

  • users
  • emails
  • sms

Each user can have many emails, and each email belongs to only one user. The same applies for text messages.

I've "ignored" all the current code, because it wasn't built on a proper way to make it an RESTful api, so I've created a new folder Api and all my code is there.

I thought it would make sense to have the following endpoints

/api/v1/users
/api/v1/users/1
/api/v1/users/1/emails
/api/v1/users/1/emails/1
/api/v1/users/1/sms
/api/v1/users/1/sms/1

In this way I can have a list of users, get all the details of a user, get a list of emails/text messages and also get all the details of a specific email/text message. However, one of the requirements is to have a page with a list of emails/text messages, so it's starting to make sense to have:

/api/v1/emails
/api/v1/emails/1
/api/v1/sms
/api/v1/sms/1

To avoid having 2 endpoints to get the same resource (/api/v1/users/1/emails/1 and /api/v1/emails/1 will return the email with id 1) I'm considering to get rid of the deep endpoints /api/v1/users/1/emails and change them to something like /api/v1/emails?user_id=1.

Is this against RESTful principles? I couldn't reach a conclusion on my research about having 2 endpoints to access the same resource, but it doesn't "feel" right. On the other hand, having /api/v1/emails?user_id=1 may rise some security/privacy concerns (for example, I need to make sure that user 1 can only access /api/v1/emails?user_id=1 and not /api/v1/emails?user_id=2), but seems more flexible because I can use it alone to get all the resources or with the user_id filter to get only specific resources.

Is there a convention for this case?

like image 513
TJ is too short Avatar asked Nov 07 '22 10:11

TJ is too short


1 Answers

It may help to review how we understand "resources" in a REST context.

Any information that can be named can be a resource: a document or image, a temporal service (e.g. "today's weather in Los Angeles"), a collection of other resources, a non-virtual object (e.g. a person), and so on. In other words, any concept that might be the target of an author's hypertext reference must fit within the definition of a resource.

/api/v1/users/1/emails
/api/v1/emails?user_id=1
/66eb6757-254e-49b4-bc8a-d04330f4482e

REST treats identifiers as semantically opaque -- general purpose clients do not use the spelling of the identifier to understand what is going on. Consider a web browser - it knows that http://example.org/cat.jpg is an image not because jpg, but because img.

That means that the server may use any spelling it likes -- any information encoded into the URI itself is done at the server's discretion and for its own use.

This isn't to say that there aren't advantages to using "guessable" spellings; just that REST is completely agnostic about whether or not identifiers should be guessable.

Choosing spellings for your identifiers that make your implementation simpler is completely within bounds.

like image 108
VoiceOfUnreason Avatar answered Nov 15 '22 06:11

VoiceOfUnreason