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.

Filter and Sort Query Parameters

The concepts of filter and sort parameters are explained in Shopware’s REST API Documentation as well. However, the http_build_query-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:

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

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

$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):

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

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 Stock API and 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 is a sensible choice. When concurrency is low, uniqid(“”, true) can be used as a fallback when adding external dependencies is not an option.