REST API design - request for mail data - which poison to choose?

We are currently developing an internal REST api. we have the following use case:

  • user (109) wants to read the message that he sent to another user (110)
  • the read user (109) is known to the application through its token credentials that it received after authentication (when executing a GET request).
  • we assume that in this example, user 109 was the sender and 110 the recipient

to summarize from the point of view of users "give me a letter that I (109) sent to 110"

in our opinion, the following URIs came, but we cannot decide which one to take:

a) GET http://localhost:9099/api/mails/109?receiverUserId=110 b) GET http://localhost:9099/api/mails?senderUserId=109&receiverUserId=110 c) GET http://localhost:9099/api/mails?receiverUserId=110 d) GET http://localhost:9099/api/mails/me/to/110 (when logged in as 109 via token credentials we know that "me" is 109) f) GET http://localhost:9099/api/mails/109/to/110 (explicit request, eg for admins … has to be guarded against illegal access) 

all links are "context-sensitive" that send one of the links to the receiver (110), will give different results that execute the GET request.

I would like to know your opinion about which URL to use.

any help is greatly appreciated.

amuses Marcel

+6
source share
3 answers

Different responses to different clients, for the same URL, are fine.

StackExchange does this:

 GET /me/comments/{toid} 

which is documented here .

Twitter also does this:

 GET /statuses/home_timeline 

which is documented here .

Both of these URLs display an authenticated user. Yes, it wins caching if users share the cache, but IMO, that's fine. Whether this breaks the "identification resource" REST limitation is probably debatable. The answer to this question, and the subsequent comment there shows me why this is debatable.

In fact, among the options you specify URLs that are not "context sensitive":

 GET /api/mails?senderUserId=109&receiverUserId=110 

This one will always return messages from 109 to 110. But if one client wants to see this result when viewing "sent" messages, the other will see this result when viewing "received" messages. What a strange ah? In addition, on the server you will need to verify that the authenticated user is 109 | 110, otherwise throw 401 UNAUTHORIZED .

I would go with something like:

 GET /mail/sent 

returns all sent mail. A:

 GET /mail/sent?to=110 (like applying a 'filter' to /mail/sent) OR GET /mail/sent/110 (clean URL) 

returns mail sent to number 110.

+2
source

Context-sensitive links are a bad idea for the REST API (in particular, this prevents caching). If you just want to use HTTP, that's fine.

Therefore, I would suggest using URLs that are not dependent on the current user and restrict access to them according to your rules.

+1
source

In my opinion, you need 2 layers:

One is the internal layer, which does not require user authentication; it is accessible only from internal components. It includes APIs such as

GET http://localhost:9099/api/mails?senderUserId=109&receiverUserId=110

The advantage of this layer is testability, reusability, and cacheability.

Another layer is the external layer, which requires user authentication and is accessible from external clients. It includes APIs such as

GET http://localhost:9099/api/mails?receiverUserId=110 .

Clients must be logged in to retrieve the token credentials, then the server can retrieve user information from this token and map the external API call to the internal API call.

You may have different authentication methods, but the inner layer will not be changed, you just need to map the various outer layers to the inner layer.

0
source

Source: https://habr.com/ru/post/913112/


All Articles