.. _rest-api-basics:

REST API Basics
===============

Communicating with the Shopware REST API
----------------------------------------

Shopware ERP's REST API is an extension of Shopware's REST API. Because of this, authentication must be performed
`as described in Showpare's REST API Documentation <https://developers.shopware.com/developers-guide/rest-api/#authentication>`_.

.. _filter_and_sort_query_parameters:

Filter and Sort Query Parameters
------------------------------------

The concepts of ``filter`` and ``sort`` parameters
`are explained in Shopware's REST API Documentation <https://developers.shopware.com/developers-guide/rest-api/#filter,-sort,-limit,-offset>`_
as well. However, the `http_build_query <http://docs.php.net/manual/en/function.http-build-query.php>`_-style encoding
of these objects into query parameters may look unfamiliar to developers who do not work with PHP on a regular basis.
``filter`` and ``sort`` query parameters are first flattened into individual key-value pairs, and are then converted
into a query string representation using the `application/x-www-form-urlencoded` encoding.

For example, given the following PHP filter structure from
`the Shopware REST API Documentation <https://developers.shopware.com/developers-guide/rest-api/#filter,-sort,-limit,-offset>`_:

.. code-block:: php

    $params = [
        'filter' => [
            [
                'property' => 'pseudoSales',
                'expression' => '>=',
                'value' => 1
            ],
            [
                'property' => 'active',
                'value' => 1
            ]
        ]
    ];

This will first be flattened to key-value-pairs like this:

.. code-block:: php

    $params = [
        "filter[0][property]" => "pseudoSales",
        "filter[0][expression]" => ">=",
        "filter[0][value]" => "1",
        "filter[1][property]" => "active",
        "filter[1][value]" => "1"
    ];

Encoding these key-value pairs as a query string using ``application/x-www-form-urlencoded`` then yields (line breaks
added for clarity):

.. code-block:: none

    filter%5B0%5D%5Bproperty%5D=pseudoSales&
    filter%5B0%5D%5Bexpression%5D=%3E%3D&
    filter%5B0%5D%5Bvalue%5D=1&
    filter%5B1%5D%5Bproperty%5D=active&
    filter%5B1%5D%5Bvalue%5D=1

.. _idempotency:

Idempotency
-----------

A recurring problem with remote APIs and distributed systems in general is that of fault tolerance in the presence of an
unreliable network. A client of the Shopware REST API may send a request for a certain operation, for example to move
one unit of stock from a bin location to a different bin location. If the client does not receive confirmation of the
operation's completion from the server, there are two possible explanations from the client's point of view:

1. The server failed to complete the operation without sending an error message.
2. The operation has completed successfully, but the confirmation was lost on the network.

This is a problem for the client, because while it will want to retry the operation in case 1, retrying in case 2 will
cause a second unit of stock to be moved, which is not what the client intended. This problem becomes even more drastic
when the client can send a request containing multiple operations to a batch endpoint and processing may fail after
completing any number of operations within the batch.

The standard solution for this is to make the operations idempotent. An operation is said to be idempotent when
repeating it any number of times still yields the same result - including leaving the system in the same state. When an
idempotent operation fails, the client can just keep repeating it until it receives a message confirming the successful
completion of the operation from the server. No matter how often the client has to retry the operation, the confirmation
message guarantees that the server performed the requested operation exactly once.

Some operations are naturally idempotent. For example, updating a warehouse's name field to "Main Warehouse" will always
yield the same system state, no matter how often the operation is repeated. For other operations, such as adding, moving
or removing a certain amount of stock, or any operation which creates new entities, idempotency must be achieved by
other means. Shopware ERP's :ref:`stock-api` and :ref:`order-shipping-api` use *idempotency keys* for this. When the
client wants to perform an operation, it generates an idempotency key and sends this along with the request. The client
must reuse the same idempotency key when it repeats the operation due to a network error. When it starts a new
operation, it must use a fresh idempotency key. The server keeps track of all idempotency keys and makes sure that all
operations identified by a single idempotency key are performed exactly once.

It is crucially important that the client manages its idempotency keys correctly, otherwise, idempotency support will
not work correctly. When idempotency keys are reused for non-retry, new requests, these requests will not be processed
correctly, even if no network error occurs.

Idempotency keys must of course be unique. We recommend using version 4 UUIDs as idempotency keys. Generators for
version 4 UUIDs are availabe for most programming languages. For PHP, `ramsey/uuid <https://github.com/ramsey/uuid>`_ is
a sensible choice. When concurrency is low, `uniqid("", true) <https://www.php.net/manual/de/function.uniqid.php>`_ can
be used as a fallback when adding external dependencies is not an option.
