Shopware 5 REST API einbinden

Oft möchte man für externe Anwendungen schnell eine Verbindung zu Shopware herstellen. Das funktioniert recht simpel mit der Shopware REST API. In diesem Artikel gehe ich kurz auf die Einrichtung ein und was man beachten sollte.

Benutzer anlegen

Erstmal sollten wir einem Benutzer API Rechte geben, denn nicht jeder in Showpare angelegte Nutzer hat diese Privilegien. Nicht ohne Grund, denn mit der API hat man viele Rechte und kann an so manche Daten kommen.

Wir können uns nun den Benutzernamen merken und den API Key kopieren. Diesen brauchen wir in Kürze in unserem Script zur Verifizierung.

API Klasse einbinden

Nun erstellen wir in unserem Shopware Root einen Ordner. Ich nenne diesen api und erstelle zwei PHP Dateien in diesem Ordner (api.php und call.php)

cd /var/www/shopware
mkdir api
cd api
touch call.php
touch api.php

In unsere api.php packen wir folgenden Code (ich empfehle euch den Code immer aktuell von HIER zu laden)

<?php
class ApiClient
{
    const METHOD_GET = 'GET';
    const METHOD_PUT = 'PUT';
    const METHOD_POST = 'POST';
    const METHOD_DELETE = 'DELETE';
    protected $validMethods = [
        self::METHOD_GET,
        self::METHOD_PUT,
        self::METHOD_POST,
        self::METHOD_DELETE,
    ];
    protected $apiUrl;
    protected $cURL;

    public function __construct($apiUrl, $username, $apiKey)
    {
        $this->apiUrl = rtrim($apiUrl, '/') . '/';
        //Initializes the cURL instance
        $this->cURL = curl_init();
        curl_setopt($this->cURL, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($this->cURL, CURLOPT_FOLLOWLOCATION, false);
        curl_setopt($this->cURL, CURLOPT_USERAGENT, 'Shopware ApiClient');
        curl_setopt($this->cURL, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
        curl_setopt($this->cURL, CURLOPT_USERPWD, $username . ':' . $apiKey);
        curl_setopt(
            $this->cURL,
            CURLOPT_HTTPHEADER,
            ['Content-Type: application/json; charset=utf-8']
        );
    }

    public function call($url, $method = self::METHOD_GET, $data = [], $params = [])
    {
        if (!in_array($method, $this->validMethods)) {
            throw new Exception('Invalid HTTP-Methode: ' . $method);
        }
        $queryString = '';
        if (!empty($params)) {
            $queryString = http_build_query($params);
        }
        $url = rtrim($url, '?') . '?';
        $url = $this->apiUrl . $url . $queryString;
        $dataString = json_encode($data);
        curl_setopt($this->cURL, CURLOPT_URL, $url);
        curl_setopt($this->cURL, CURLOPT_CUSTOMREQUEST, $method);
        curl_setopt($this->cURL, CURLOPT_POSTFIELDS, $dataString);
        $result = curl_exec($this->cURL);
        $httpCode = curl_getinfo($this->cURL, CURLINFO_HTTP_CODE);

        return $this->prepareResponse($result, $httpCode);
    }

    public function get($url, $params = [])
    {
        return $this->call($url, self::METHOD_GET, [], $params);
    }

    public function post($url, $data = [], $params = [])
    {
        return $this->call($url, self::METHOD_POST, $data, $params);
    }

    public function put($url, $data = [], $params = [])
    {
        return $this->call($url, self::METHOD_PUT, $data, $params);
    }

    public function delete($url, $params = [])
    {
        return $this->call($url, self::METHOD_DELETE, [], $params);
    }

    protected function prepareResponse($result, $httpCode)
    {
        echo "<h2>HTTP: $httpCode</h2>";
        if (null === $decodedResult = json_decode($result, true)) {
            $jsonErrors = [
                JSON_ERROR_NONE => 'No error occurred',
                JSON_ERROR_DEPTH => 'The maximum stack depth has been reached',
                JSON_ERROR_CTRL_CHAR => 'Control character issue, maybe wrong encoded',
                JSON_ERROR_SYNTAX => 'Syntaxerror',
            ];
            echo '<h2>Could not decode json</h2>';
            echo 'json_last_error: ' . $jsonErrors[json_last_error()];
            echo '<br>Raw:<br>';
            echo '<pre>' . print_r($result, true) . '</pre>';

            return;
        }
        if (!isset($decodedResult['success'])) {
            echo 'Invalid Response';

            return;
        }
        if (!$decodedResult['success']) {
            echo '<h2>No Success</h2>';
            echo '<p>' . $decodedResult['message'] . '</p>';
            if (array_key_exists('errors', $decodedResult) && is_array($decodedResult['errors'])) {
                echo '<p>' . join('</p><p>', $decodedResult['errors']) . '</p>';
            }

            return;
        }
        echo '<h2>Success</h2>';
        if (isset($decodedResult['data'])) {
            echo '<pre>' . print_r($decodedResult['data'], true) . '</pre>';
        }

        return $decodedResult;
    }
}

Zum testen unserer API Verbindung fügen wir folgenden Code noch in unsere call.php

<?php

include_once ('api.php');


$client = new ApiClient(
//URL of shopware REST server
	'http://DEINEURL.DE/api',
	//Username
	'demo',
	//User's API-Key
	'DEINAPICODE'
);

$client->get('articles/2');
?>

Beim Aufruf von http://DEINEURL.DE/api/call.php sollten nun enkodierte Artikeldetails erscheinen:

So einfach bindet Ihr die REST API in euer Shopware ein und könnt nun bequem über eine Schnittstelle Artikeldaten, Bestellstatus und ähnliches abfragen. Natürlich macht das mehr Sinn in einer anderen Anwendung als Shopware selbst – dient aber hier der Einfachheit halber.

10 Antworten auf „Shopware 5 REST API einbinden“

  1. Super Erklärung! Es wäre genial, wenn Du so ein Tutorial auch für die Shopware 6 API bereitstellen könntest. Ist das möglich?
    Viele Grüße
    Peter

  2. Genau so etwas suche ich für Java!
    Ich möchte außerdem die Information des Umsatzes aus der Api holen. Haben Sie vielleicht dafür einen Hinweis für mich?
    Vielen Dank und Super Tutorial!

  3. Hallo Micha,

    sehr gute Anleitung und vor allem verständlich erklärt!
    Wie würde sich der Befehl in der call.php denn abändern, wenn man bspw. mehrere Artikel anhand der Bestell-Nr. löschen will und würden dabei alle mit dem Produkt verknüpften Inhalte wie Bilder etc. mit gelöscht werden?

    Viele Grüße
    Stefan

  4. Hallo Micha,

    kannst du mal ein Beispiel erstellen,
    wie ein Push aussehen muss, um einen neuen Artikel anzulegen?

    Danke und Grüße
    Marcus

  5. Vielen Dank. Dadurch habe ich einen ersten Eindruck bekommen, was zu tun ist um Shopware und REST API zusammen zu bringen. Allerdings brauche ich Shopware 6.

  6. Hallo,
    ich versuche gerade Kundendaten aus Shopware5 per API über PowerQuery zuladen. Klappt au ch schon ganz gut. Nun habe ich 2 Fragen:
    1. wie übergebe ich den API Key und
    2. wie kann ich das Limit von 1000 Datensätzen aufheben.

    Für eine Antwort bin ich sehr dankbar.

    1. Hi Werner, danke für deine Anfrage, aktuell liegt mein Fokus allerdings auf Shopware 6. Aber eventuell meldet sich noch jemand auf deine Frage.

  7. Guten Abend,
    vielen Dank für diese Anleitung, sie hat mir vor 2017/18 schon viel erleichter. Seit einiger Zeit sind wir auf der Shopware-Version 5.7.6 und seit eben diesem Update (von 5.7.2) laufen die Scripte in einen 500er. Heute hab ich nun alle Teile der API versucht zu debuggen und komme aber nicht drauf, warum die Laufzeiten von zuvor 30-40 Sekunden für etwa 4500 Artikel plötzlich auf 900+ Sekunden und damit in den Timeout erhöht hat… Ist Ihnen / euch da bekannt, dass die API, bzw. die ApiClass angepasst werden muss?!
    Viele Grüße,
    Bertl

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert