
Naming complex actions in a REST API
In all the manuals in the REST descriptions, they give simple examples, such as the users for you, they will be the / users resource, here is one user for you, it will be / users / [id] and the actions to add / delete / change with it.
But what if the actions are complex or complex and do not fit into GET \ POST \ DELETE?
Trying to figure it out, he asked a question on the toaster and continued further excavations.
I found an exhaustive article , but I can’t handle the full translation, so I will summarize the conclusions made in a short note.
Suppose we are writing a nuclear suitcase application with a REST interface. The functionality will be as follows:
1. Actions with the [id] rocket: launching around the country, selling to the country, servicing, writing off to the scrap
It is logical to use the resource / missiles / [id], but for these actions it is incorrect and uninformative to use PUT or PATCH.
Wrong options:
1. You can expand the list of standard HTTP methods. But there may be difficulties with the support of different clients, ready-made libraries and filtering server settings.
2. / missiles / [id]? Action = launch makes the entire REST approach meaningless, as Most of the functionality will be in actions.
3. / missiles / [id] / launch - dragging a verb into a resource address is incorrect.
4. LINK / missiles / [id] / countries / [country_id] / - it is not clear what exactly is happening - a sale or a nuclear strike.
The correct option.
Correctly access the properties of the resource. Those. not the action "/ users / [id] / disable", but the resource "/ users / [id] / disable d ", to which the standard GET \ POST \ methods are logically applicable ...
Launching the rocket: POST / missiles / [id] / countries -landed / [country_id]
Rocket sale: POST / countries / [country_id] / missiles-bought / [id] or POST / missiles / [id] / owner / [country_id]
Service: POST / missiles / [id] / on- service
UPD:
Rocket launch: POST / missiles / [id] / launcher {target: [country_id]}
Rocket sale: PATCH / missiles / [id] {owner: [country_id]}
Service: PUT / missiles / [id] / on-service or if there is a separate missile service POST / missiles_service / {missile: [id]}
Write to the scrap: DELETE / missiles / [id] or if there may be other options for “deletion” »PUT / missiles / [id] / utilized
2. Launch any suitable rocket around the country [country_id]
Assume that the missiles are very dofig and do a search first, and then launch overhead and for a long time, you need one request for instant execution.
Wrong options:
1. Perform a “launch” on the entire collection of missiles ([id] of a specific missile we do not know).
2. The action "get a rocket" from the selected country.
Correct option
If the action is complex and cannot be expressed through atomic actions on a resource-object, a resource-process is created. Similarly, a resource process is created if you want to perform a composite action with complex business logic (consisting of several dependent actions), for example, a banking transaction.
Those. the creation of the Rocket Launch resource will be correct.
Then POST will launch a rocket, GET will know the status of the process, DELETE cancel it. At the same time, consistency is maintained, i.e. the rocket is already flying, and the status of the country “still exists”.
Bonus:
It turned out that many large companies have no idea what REST is, and this name is used in the description. So you can’t trust everything that is writtenon the fence, even for large people.
A couple of examples of Achtungs:
The only decent REST API I was able to discover GitHub . Amen.
But what if the actions are complex or complex and do not fit into GET \ POST \ DELETE?
Trying to figure it out, he asked a question on the toaster and continued further excavations.
I found an exhaustive article , but I can’t handle the full translation, so I will summarize the conclusions made in a short note.
Briefly about the problem:
The main difference between REST and RPC is the approach that the URL is the address of the resource, actions with which are performed using standard HTTP methods: GET \ POST \ DELETE \ PATCH \ ... In short, the resource is a noun, not a verb.
Those. if you see something like / api / users / do_some_cool_staff or GET / users / 1? action = delete, know - this is not REST!
Suppose we are writing a nuclear suitcase application with a REST interface. The functionality will be as follows:
1. Actions with the [id] rocket: launching around the country, selling to the country, servicing, writing off to the scrap
It is logical to use the resource / missiles / [id], but for these actions it is incorrect and uninformative to use PUT or PATCH.
Wrong options:
1. You can expand the list of standard HTTP methods. But there may be difficulties with the support of different clients, ready-made libraries and filtering server settings.
2. / missiles / [id]? Action = launch makes the entire REST approach meaningless, as Most of the functionality will be in actions.
3. / missiles / [id] / launch - dragging a verb into a resource address is incorrect.
4. LINK / missiles / [id] / countries / [country_id] / - it is not clear what exactly is happening - a sale or a nuclear strike.
The correct option.
Correctly access the properties of the resource. Those. not the action "/ users / [id] / disable", but the resource "/ users / [id] / disable d ", to which the standard GET \ POST \ methods are logically applicable ...
Rocket sale: POST / countries / [country_id] / missiles-bought / [id] or POST / missiles / [id] / owner / [country_id]
Service: POST / missiles / [id] / on- service
UPD:
Rocket launch: POST / missiles / [id] / launcher {target: [country_id]}
Rocket sale: PATCH / missiles / [id] {owner: [country_id]}
Service: PUT / missiles / [id] / on-service or if there is a separate missile service POST / missiles_service / {missile: [id]}
Write to the scrap: DELETE / missiles / [id] or if there may be other options for “deletion” »PUT / missiles / [id] / utilized
2. Launch any suitable rocket around the country [country_id]
Assume that the missiles are very dofig and do a search first, and then launch overhead and for a long time, you need one request for instant execution.
Wrong options:
1. Perform a “launch” on the entire collection of missiles ([id] of a specific missile we do not know).
2. The action "get a rocket" from the selected country.
Correct option
If the action is complex and cannot be expressed through atomic actions on a resource-object, a resource-process is created. Similarly, a resource process is created if you want to perform a composite action with complex business logic (consisting of several dependent actions), for example, a banking transaction.
Thought more detailed
Let us relook at what Roy Fielding's dissertation says about resource: "... any concept that might be the target of an author's hypertext reference must fit within the definition of a resource ....". Business capabilities / processes can neatly fit the definition of resources. In other words, for complex business processes spanning multiple resources, we can consider the business process as a resource itself. For example, the process of setting up a new customer in a banking domain can be modeled as a resource. CRUD is just a minimal business process applicable to almost any resource. This allows us to model business processes as true resources which can be tracked in their own right.
Those. the creation of the Rocket Launch resource will be correct.
Then POST will launch a rocket, GET will know the status of the process, DELETE cancel it. At the same time, consistency is maintained, i.e. the rocket is already flying, and the status of the country “still exists”.
Bonus:
It turned out that many large companies have no idea what REST is, and this name is used in the description. So you can’t trust everything that is written
A couple of examples of Achtungs:
- Twitter
POST friendships / create
POST friendships / destroy
POST friendships / update
GET friendships / show
GET friends / list - Mail.ru
All API method calls are GET or POST HTTP requests to the URL www.appsmail.ru/platform/api with some set of parameters. [...] At the moment, the API does not distinguish between GET and POST requests.
The only decent REST API I was able to discover GitHub . Amen.