Radmation
Radmation

Reputation: 1524

RESTful best practice. Does this violate the Stateless constraint?

I have a specific example regarding staying true to the RESTful principles, specifically:

Stateless: One client can send multiple requests to the server; however, each of them must be independent, that is, every request must contain all the necessary information so that the server can understand it and process it accordingly. In this case, the server must not hold any information about the client state. Any information status must stay on client – such as sessions. (quoting from: https://www.dineshonjava.com/what-is-rest-and-rest-architecture-and-rest-constraints/)

Now let's say a User can create a new Event by posting this:

{
  "name": "string",
  "radius": 50,
  "status": 0,
  "location": {
    "lat": 0,
    "lng": 0
  },
  "commonUserId": 0
}

The application is set up in a way where the user can accomplish the same thing by posting this instead:

{
  "name": "testing",
  "radius": 50,
  "status": 0,
  "location": {
    "lat": 0,
    "lng": 0
  }
}

Make note that the commonUserId is not present in the second example. The commonUserId is a foreign key in the DB and necessary to create a new record.

The reason this is not needed to create a new record is because the application is using the access token provided by the client to get the user id (authenticated user id) using some logic. Then the app is then using that retrieved id (from logic) to do the insert/record creation.

Now my question is does this violate the stateless constraint of a restful api?

I can make an argument both ways:

No this is not a violation because all data was provided by the client technically. Although the client is depending on some application logic to make it happen.

Yes this is a violation because the client is depending on application logic to get the user id. The application had to look-up the user id opposed to the client sending it over.

The reason I ask this is because I can make the id part of the information that the client needs to provide, however since the accessToken is required the application can use that to get the id...

Maybe I am overthinking this too much? What is best practice? Is it up to the developer is this situation? Anyone else encounter this problem? How would you handle this and why?

Side note: I am building this with LoopBack.

Edit:

So I suppose there is an underlying question here. Is it ok to rely on the access token as a means to get other pieces of information?

Upvotes: 2

Views: 387

Answers (3)

Serg
Serg

Reputation: 2427

I think you are mixing two things here - request authentication and request data.

Access token ensures that request data should be processed if the token is valid.

Then your application's business logic is responsible to interpret request data, map it on your data model and decide what to use as user id while creating event. Imagine that access token just identifies user Admin as request's originator and request data contains user Boy's id as commonUserId for whom event is creating by the request.

Using access token to identify user is common practice for loopbackjs framework.

Upvotes: 1

VoiceOfUnreason
VoiceOfUnreason

Reputation: 57259

Now my question is does this violate the stateless constraint of a restful api?

The definitive definition of stateless (in the context of REST) comes from chapter three of Roy Fielding's thesis, where he describes the Client-Stateless-Server hierarchical style

The client-stateless-server style derives from client-server with the additional constraint that no session state is allowed on the server component. Each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server.

... Scalability is improved because not having to store state between requests allows the server component to quickly free resources and further simplifies implementation.

Chapter 6 of Fielding's thesis, where he discusses session cookies, describes part of the problem of storing session state on the server.

When the browser's history functionality (the "Back" button) is subsequently used to back-up to a view prior to that reflected by the cookie, the browser's application state no longer matches the stored state represented within the cookie. Therefore, the next request sent to the same server will contain a cookie that misrepresents the current application context, leading to confusion on both sides.

So you can use the information in the message-body, and use "application logic" to transform it. Similarly, you can use information in the message-headers, and use "application logic" to transform that.

Where you get into trouble is using information in the request to look up session state - aka something the client told you in an earlier message.

Is it ok to rely on the access token as a means to get other pieces of information?

It depends?

"This request includes access token 12345, therefore the commonUserId should be 67890, because that's always true for token 12345." That should be fine.

"This request includes access token 12345, therefore the commonUserId should be 67890, because there was an earlier request with token 12345 that told us to use commonUserId 67890" <-- not stateless.

Kristopher Sandoval has a good essay on stateful vs stateless web services that may help clarify things for your case.

Upvotes: 1

na-98
na-98

Reputation: 889

You're not overthinking. It's actually great that you are keeping these things in mind when writing code. Someone years down the line will actually thank you for making sound decisions when they are looking at the code.

Now on to the topic. If I were you, I would not have the "commonUserId" and I'm saying this from a security perspective. Because I'd have to validate the commonUserId value either way to see if it first exists in my system (don't trust client input) or it actually belongs to the authenticate users (access token in your case). So for that reason I'd do away with it and rely on access token and app logic to identify the user.

Case can be made either way indeed but ensure you don't blindly trust client input even though application is setting that value in the first place.

Good luck!

Upvotes: 1

Related Questions