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.
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
Hi Peter,
danke. Ich kann nochmal ein simpleres Konstrukt aufbauen, aktuell gibt es zur neuen API in Shopware 6 schon einen Artikel -> https://www.the-cake-shop.de/shopware-platform-api/
Vielleicht hilft dir das bereits weiter.
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!
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
Hallo Micha,
kannst du mal ein Beispiel erstellen,
wie ein Push aussehen muss, um einen neuen Artikel anzulegen?
Danke und Grüße
Marcus
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.
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.
Hi Werner, danke für deine Anfrage, aktuell liegt mein Fokus allerdings auf Shopware 6. Aber eventuell meldet sich noch jemand auf deine Frage.
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