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.

    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 ...

    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.

    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 on the fence, even for large people.

    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.

    Also popular now: