Rest uri design to change the status of a resource

I have a resource that can be accessed in the URI /resources/{resource_identifier} , and it has a status property that I want to be available. I thought of several options for this, which would be “best” or “most RESTfull”?

Option 1 Adding actions to the URI, and the presence of the client POST for this URI

 /resources/{resource_identifier}/void /resources/{resource_identifier}/open /resources/{resource_identifier}/close 

It looks awkward.


Option 2 Use the request parameter in the URI and set the client to PATCH on these

 /resources/{resource_identifier}?transition=void /resources/{resource_identifier}?transition=open /resources/{resource_identifier}?transition=close 

Option Three Use the request payload and the client PUT

 /resources/{resource_identifier} 

payload parameters:

 { ..., "status" :"void" } { ..., "status" :"open" } { ..., "status" :"close" } 

Or maybe something else?

+13
source share
4 answers

The first option is clearly not REST; you have "actions" in the URI and use POST , which should create a new resource that you are not explicitly trying to do.

Let's only look at the URI format. The second option is improving, but query strings of this nature are larger for reading data. Nothing really prevents you from doing it this way. Option 3 has the best URI format, it only refers to which resource you want to reference in your request.

If we consider the request method. In my book, this is quite simple, I believe that status is only one field of this resource, therefore, if you do only a partial update, you correct the resource, and therefore PATCH is the method that should be used. In case of accident, "status" is the only property, then changing the status completely changes the resource, and therefore PUT will be acceptable; but I doubt that this is true.

Accordingly, the URIs of the third option, combined with the use of PATCH , are probably the best option.

 PATCH /resources/{resource_identifier} { "status" :"close" } 

Of course, you could also combine this with the concept of expanding certain attributes through your own URI, as if they were the resource itself. Honestly, I don't like this because it seems rather strange and only works on one attribute at a time. However, if this is what you wanted to use, you could have something like:

 PUT /resources/{resource_identifier}/status close 

Keep in mind that there is no “right” way to do REST, just “not bad”. This is a style, not a set of rules.

I also suggest that you think that the ability to accept many formats is a desirable feature, generally speaking. Thus, the first option is usually easier to work with. You can take JSON, as in the example, or exchange it for XML <status>close</ status> , or a pair of status=closed key pairs, etc.

+17
source

Why not have a “status” as a resource. You can control it. Also assume that the status status already exists, created as part of the creation of the resource {resource_identifier} , and the status already has a default value.

Then the business logic should simply “update” the status with the rest of the call, and therefore it is necessary to use “PUT”.

state transfer to the body-remote is updated

 PUT: /resources/{resource_identifier}/status/ Body: {void | open | close } 
+12
source

The second option looks better because you maintain a RESTful URL structure and do not add RPC style methods to the end.

Why not just do it:

PUT to /resources/:id and send the transition=void data with the request.

It behaves the same as if you were receiving a POST request, just extract the data from the request body.

+1
source

There are many cases where state changes have a lot of business logic. Although the answers are based on “rest standards,” I think there are cases that don't just change the state of the mind.

For example, if the system must cancel the order. It is not easy to change the state, since the order has many states, and each change represents a lot of logic (notifications, checks, etc.)

In cases of use:

 PATCH /order/1 { "status" :"cancelled" } 

I can assure you that the logic will be scattered by the client and server, it will be difficult to maintain, and it will not have elegant code (especially on the server side, which will check the previous, subsequent state, if the change is sequential, and it will be mixed with responsibility for update ).

I find it easier to have a cancel method and do my job. I think in many cases this is more elegant:

 PATCH: /order/1/cancel //you could use the body with some cancellation data. 

The following link can help you: https://phauer.com/2015/restful-api-design-best-practices/#keep-business-logic-on-the-server-side

0
source

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


All Articles