How about using URI path variables for HTTP POST?

I searched a lot but could not find the correct answer to my question regarding my conditions. I am creating a REST API, and the case that seems to me to be a boundary case is as follows:

-I am dealing with two entities, users and roles. A user can assign multiple roles.
To assign a role to a user, the role must already be in the database.
-To assign a role to a user, the only thing that is needed is the "code" of the role, that is, a short string.
The uri path template currently used:
--Sources: localhost: 8080 / api / users
--Given User: localhost: 8080 / api / users / {userId}
- Roles of this user: localhost: 8080 / api / users / {userId} / role

Now, in order to "associate" a given user with a given role, I get two options.
- The first is the one that sounds like best practice in any scenario, sending the post data in the body, possibly as JSON.
- Another, sending it through the uri and with an empty body. For example, to associate a user with id U001 with role R001, you would need to send to the following uri that does not send data in the body: localhost: 8080 / api / users / U001 / role / R001

The point is that I don't mind using the first option and it seems to be the best and most correct, but in this particular case, I'm not sure if it's better to send an almost empty body (because it only contains the role id, a very short string) by sending its in "localhost: 8080 / api / users / U001 / role" or by passing the body and just sending the role id via uri as a path parameter like localhost: 8080 / api / users / U001 / role / R001

Thanks everyone for your help.


source to share

2 answers

There is nothing wrong with having a role in a URI. Your intuition was on the right track. I would do it like this.

PUT: locahost: 8080 / api / users / {userid} / role / {roleId}

And that's why.

FIRST: The PUT verb is Idempotent . In other words (taken straight from the spec)

... the side effects of N> 0 identical queries are the same as for a single query.

This is what I assume you want in this regard. You don't want your state store to have multiple entries for each user and role instance. The user should feel at ease making the same PUT request without compromising the system (adding duplicate entries).

When you do the same with POST, I expect a new record to be created for each request.

SECOND: The PUT verb must identify a specific resource. (taken straight from the spec)

... The PUT request identifies the entity enclosed with the request - the user agent knows what the URI is and the server MUST NOT try to apply the request to another resource. If the server wishes the request to be applied to a different URI, it MUST send a 301 (moved persistent) response; the user agent MAY then make its own decision to redirect the request.

What if the R102 role becomes deprecated and the R104 is preferred? Revert 301 (moves permanently) with HEADER (Location: localhost: 8080 / api / users / {userid} / role / R104).

FINALLY: When everything works well. Return 201 (generated) on creation and 200 (no content) for each subsequent request to the same URI. If they provide a role that is not on the system, return 501 (Not Implemented).



Hmm - in this case, POST with 302 can be a little messy.

Why not a very simple "PUT" / "DELETE" with suggested URIs?

Simple; The 20X value succeeded, perhaps around 30X to indicate that it was already there - and something else glitching?



All Articles