Zum Inhalt springen
APIs, Middleware & Architektur

Massenimport aus dem ERP: die Sync-API von Shopware nutzen

Massenimport aus dem ERP in Shopware: Sync-API mit Upsert und Delete, Paketgrößen nach Server-Grenzen, Indexierung über die Message Queue und Delta-Abgleich.

19 Min. Lesezeit Sync-APIMassenimportShopwareWarenwirtschaft

Kurz und einfach erklärt

Vor großen Aktionen ändert die Warenwirtschaft viele Preise und Bestände. Diese Daten müssen schnell in den Shop.

Schickt man jeden Artikel einzeln, dauert das lange. Der Shop wird dabei langsam.

Shopware hat dafür einen Sammelweg. Er heißt Sync-API. Er nimmt viele Artikel in einem Paket an.

Danach muss der Shop Suche und Listen neu ordnen. Das kann eine Warteschlange im Hintergrund tun. Dort arbeiten kleine Programme die Aufgaben ab.

Gut ist es, nur die Daten zu schicken, die sich geändert haben. Wir helfen Ihnen, den Import so einzurichten.

Vor dem Aktionsgeschäft im November ändert sich in der Warenwirtschaft vieles auf einmal: neue Preise, Streichpreise, Bestände für Aktionsartikel, frisch angelegte Sets. Damit die Daten rechtzeitig im Shop stehen, schreibt das ERP Tausende Datensätze in Shopware. Läuft das als Einzelaufruf je Artikel und mit Indexierung im laufenden Request, bremst der Import sich selbst und den Shop gleich mit. Shopware bietet für diesen Fall einen eigenen Weg: die Sync-API, die mehrere Schreiboperationen in einem Aufruf bündelt (Shopware Admin-API-Referenz). Dieser Beitrag zeigt, wie ein Sync-Paket aufgebaut ist, wie Sie die Paketgröße an den Grenzen von Webserver und PHP ausrichten, warum die Indexierung in die Message Queue gehört, wie viele Worker sinnvoll sind, wie Sie Fehler je Operation auswerten und warum ein Delta-Abgleich den nächtlichen Vollabgleich im Alltag ersetzt.

Das Wichtigste in Kürze

  • Die Sync-API nimmt unter /api/_action/sync Upsert- und Delete-Operationen für mehrere Entitäten in einem Aufruf an. Seit Version 6.5 schreibt sie alle Datensätze eines Aufrufs in einer Transaktion (Shopware UPGRADE-6.5).
  • Die Paketgröße richtet sich nach den Grenzen der Umgebung: nginx nimmt ohne Anpassung höchstens 1 MB Request-Body an (nginx-Dokumentation), PHP beendet ein Skript in der Voreinstellung nach 30 Sekunden (PHP-Handbuch).
  • Der Header indexing-behavior: use-queue-indexing verlegt die Indexierung aus dem Request in die Message Queue. Produktindexierung gilt dort in der Regel als langsam und lässt sich bei Bedarf auf einen eigenen Transport mit eigenen Workern legen (Shopware-Dokumentation).
  • Bis zu drei Worker-Prozesse nennt Shopware für die Datenbank-Queue als normal, darüber braucht es einen eigenen Message-Broker. Fehlgeschlagene Nachrichten werden 3-mal wiederholt und danach gelöscht (Shopware-Dokumentation).
  • Ein Delta-Abgleich überträgt nur geänderte Preise, Bestände und Löschungen. Fehlerpfade aus Operationsschlüssel und Position führen jeden abgelehnten Datensatz auf den ERP-Satz zurück, der korrigiert werden muss.

Warum Einzelaufrufe beim Massenimport bremsen

Viele Anbindungen beginnen mit dem naheliegenden Weg: Für jeden geänderten Artikel schickt die Middleware einen eigenen Aufruf an die Admin-API von Shopware. Bei ein paar Dutzend Änderungen am Tag fällt das kaum auf. Vor einer Aktion sieht es anders aus. Dann ändern sich Preise und Bestände für große Teile des Sortiments gleichzeitig, und jeder dieser Aufrufe durchläuft dieselben Schritte: Verbindung aufbauen, Token prüfen, Daten validieren, schreiben, Ereignisse auslösen und abhängige Daten neu berechnen.

Der letzte Schritt ist der teure. Je nachdem, welche Daten geschrieben wurden, stößt Shopware verschiedene Indexierungsprozesse an; bei großen Importen erzeugt das hohe Last auf dem Server (Shopware Admin-API-Referenz). Läuft diese Arbeit im selben Request wie der Schreibvorgang, wartet der Import auf die Indexierung, und PHP-Prozesse, die eigentlich Besucher bedienen sollen, sind mit Neuberechnungen beschäftigt. Der Shop wird langsamer, und zwar genau in den Tagen, in denen Kundschaft Preise vergleicht.

Dazu kommt das Verhalten auf der ERP-Seite. Cloud-ERP-Systeme begrenzen die Zahl der Anfragen je Zeitfenster; wie sich ein Export dort steuern lässt, beschreibt unser Beitrag zu API-Limits beim Massenimport. Auf der Shop-Seite hilft ein anderes Werkzeug: weniger, dafür größere Aufrufe, deren Indexierung entkoppelt im Hintergrund läuft. Typische Anzeichen, dass ein Import am falschen Ende ansetzt:

  • Der Importlauf dauert Stunden und überschneidet sich mit den Zeiten, in denen bestellt wird.
  • Die Antwortzeiten der Storefront steigen, solange der Import läuft.
  • Nach dem Import zeigen Listing und Suche noch einige Zeit alte Preise oder Bestände.
  • Ein Abbruch mitten im Lauf hinterlässt einen Teil der Artikel mit neuen, einen Teil mit alten Werten.
  • Im Protokoll lässt sich nicht nachvollziehen, welcher ERP-Datensatz abgelehnt wurde und warum.

Was der Sync-Endpunkt kann

Die Sync-API ist eine Ergänzung der Admin-API, mit der sich mehrere Schreiboperationen, also Anlegen, Ändern und Löschen, in einem Aufruf ausführen lassen. Alle Entitäten, die über die Admin-API schreibbar sind, lassen sich auch über die Sync-API schreiben (Shopware Admin-API-Referenz). Der Endpunkt liegt unter /api/_action/sync und erwartet einen POST-Request mit JSON im Body.

Ein Aufruf enthält eine Liste von Operationen. Jede Operation nennt die Aktion (upsert oder delete), die Entität und die Nutzlast: beim Upsert eine Liste von Datensätzen, beim Delete eine Liste von IDs. Innerhalb eines Requests lassen sich so verschiedene Entitäten gemeinsam schreiben, und zur leichteren Fehlersuche bekommt jede Operation einen eigenen Schlüssel (Shopware Admin-API-Referenz). Für einen Import aus der Warenwirtschaft heißt das: Preise, Bestände und Kategoriezuordnungen eines Laufs reisen in einem Paket. Das folgende Beispiel aktualisiert den Bestand zweier Artikel, ordnet einen Artikel über seine Artikelnummer einer Kategorie zu und entfernt einen anderen aus einer Kategorie.

sync-paket.http
POST /api/_action/sync
Content-Type: application/json
indexing-behavior: use-queue-indexing
sw-skip-trigger-flow: true

{
  "bestand-lauf-0412": {
    "entity": "product",
    "action": "upsert",
    "payload": [
      { "id": "0190c8a2e5f47b1d9a3c6e8f2b4d6a10", "stock": 140 },
      { "id": "0190c8a2e5f47b1d9a3c6e8f2b4d6a11", "stock": 0 }
    ]
  },
  "kategorie-zuordnen-lauf-0412": {
    "entity": "product_category",
    "action": "upsert",
    "payload": [
      {
        "productId": { "resolver": "product.number", "value": "A-10023" },
        "categoryId": "0190c8a2e5f47b1d9a3c6e8f2b4d6a55"
      }
    ]
  },
  "kategorie-entfernen-lauf-0412": {
    "entity": "product_category",
    "action": "delete",
    "payload": [
      {
        "productId": "0190c8a2e5f47b1d9a3c6e8f2b4d6a10",
        "categoryId": "0190c8a2e5f47b1d9a3c6e8f2b4d6a77"
      }
    ]
  }
}

Die Antwort listet unter data die geschriebenen IDs je Entität, dazu notFound und deleted (Shopware Admin-API-Referenz). Den Operationsschlüssel sollten Sie sprechend wählen, etwa aus Datenart und Laufnummer: Er taucht in Fehlermeldungen als Teil des Pfads auf und verbindet so jede Meldung mit dem Lauf, aus dem der Datensatz stammt. Die beiden Header im Beispiel verlegen die Indexierung in die Queue und unterdrücken Flows; beide behandelt dieser Beitrag weiter unten.

Upsert, Delete und Fremdschlüssel im Paket

Anders als die übrige Admin-API unterscheidet die Sync-API nicht zwischen Anlegen und Ändern. Sie prüft je Datensatz, ob die Entität schon existiert, und aktualisiert sie, wenn eine ID übergeben wurde; andernfalls entsteht eine neue Entität (Shopware Admin-API-Referenz). Für einen Import ist das bequem und zugleich die häufigste Fehlerquelle: Wer keine ID mitschickt oder je Lauf eine neue erzeugt, legt Dubletten an, statt zu aktualisieren. Die ID eines Artikels muss deshalb aus einem festen Schlüssel abgeleitet und im Daten-Mapping zwischen ERP und Shop hinterlegt sein. Für einen ERP-Import sind diese Bausteine der Sync-API besonders wichtig:

Upsert

Legt an oder aktualisiert, je nachdem, ob die ID existiert. Die ID kommt aus dem Mapping, nicht aus dem Zufallsgenerator des Importlaufs.

Delete

Löscht Datensätze über ihre IDs. Bei Zuordnungstabellen wie product_category sind es die beiden Fremdschlüssel, die zusammen den Primärschlüssel bilden.

Löschen per Kriterium

Entfernt Zuordnungen über einen Filter, ohne jede Kombination aufzuzählen. Kriterium und Payload lassen sich nicht in derselben Operation kombinieren.

Fremdschlüssel-Resolver

Verweist über lesbare Schlüssel wie Artikelnummer oder ISO-Code auf andere Entitäten. Die API löst sie vor dem Schreiben in UUIDs auf.

Operationsschlüssel

Benennt jede Operation im Paket. Fehlermeldungen tragen ihn im Pfad, das Protokoll findet damit den Lauf und die Datenart.

Flows unterdrücken

Der Header sw-skip-trigger-flow verhindert, dass ein Import Flows auslöst, etwa Mails an Kunden nach einer Datenänderung.

Die Fremdschlüssel-Resolver sind für ERP-Importe besonders nützlich, weil das ERP die UUIDs von Shopware in der Regel nicht kennt, wohl aber Artikelnummern und ISO-Codes. Die Referenz führt product.number als Beispiel; mit Version 6.7.11.0 kamen sieben weitere Resolver hinzu, darunter currency.iso_code, tax.tax_rate und payment_method.technical_name (Shopware Release Notes 6.7.11.0). tax.tax_rate löst nur auf, wenn genau ein Steuersatz mit diesem Wert existiert. Lässt sich ein Wert nicht auflösen, scheitert der Request; mit nullOnMissing fällt die Referenz stattdessen auf null zurück (Shopware Admin-API-Referenz). Im Quellcode wendet Shopware die Resolver nur bei Upsert-Operationen an, Löschungen brauchen weiterhin die UUID (Shopware-Quellcode). Prüfen Sie vor dem Einsatz, welche Resolver Ihre installierte Version kennt.

Beziehungen nicht über das Hauptobjekt löschen

Eine Zuordnung, etwa ein Artikel in einer Kategorie oder eine Eigenschaft am Artikel, verschwindet nicht, wenn sie im Upsert des Artikels fehlt. Gelöscht wird sie als Delete auf der Zuordnungsentität, zum Beispiel product_property; die Referenz beschreibt dafür auch das Löschen über Kriterien (Shopware Admin-API-Referenz). Ein Import, der nur Artikel schreibt, sammelt sonst über die Monate verwaiste Zuordnungen.

Die passende Paketgröße finden

Eine feste Obergrenze für Datensätze je Aufruf nennt die Referenz zur Sync-API nicht. Die Grenze setzt die Umgebung, und zwar an mehreren Stellen zugleich. Zuerst begrenzt der Webserver die Größe des Request-Bodys: nginx nimmt ohne Anpassung höchstens 1 MB an und antwortet bei größeren Bodys mit dem Status 413 (nginx-Dokumentation). Nach dem HTTP-Standard heißt 413, dass der Server die Anfrage ablehnt, weil ihr Inhalt größer ist, als er verarbeiten will oder kann (RFC 9110).

Dahinter folgt PHP. Ein Skript darf in der Voreinstellung 128 MB Speicher belegen (PHP-Handbuch); Shopware verlangt für den Betrieb mindestens 512 MB und eine maximale Ausführungszeit von mindestens 30 Sekunden (Shopware-Dokumentation). Das gesamte Paket wird beim Empfang dekodiert, validiert und in einer Transaktion geschrieben; ein großes Paket belegt also mehr Speicher und hält Datenbanksperren länger. Für die Datenbank empfiehlt Shopware einen max_allowed_packet von mindestens 32 MB (Shopware-Dokumentation). Die wichtigsten Grenzen im Überblick:

GrenzeVoreinstellungWo sie greiftFolge bei Überschreitung
client_max_body_size (nginx)1 MB (nginx-Dokumentation)im Webserver, bevor PHP das Paket siehtStatus 413, das Paket erreicht Shopware nicht
memory_limit (PHP)128 MB (PHP-Handbuch), Shopware verlangt mindestens 512 MB (Shopware-Dokumentation)beim Dekodieren, Validieren und Schreiben des PaketsAbbruch mit Speicherfehler, Ergebnis des Laufs unklar
max_execution_time (PHP)30 Sekunden (PHP-Handbuch)im PHP-Skript des Web-Requests, einschließlich synchroner IndexierungAbbruch des Skripts, der Client erhält keine verwertbare Antwort
max_allowed_packet (Datenbank)Shopware empfiehlt mindestens 32 MB (Shopware-Dokumentation)bei großen Anweisungen zwischen PHP und DatenbankFehler beim Schreiben, das Paket wird nicht übernommen

Daraus folgt kein Universalwert, sondern ein Messverfahren. Datensätze sind unterschiedlich schwer: Ein Bestandsabgleich trägt je Artikel eine ID und eine Zahl, ein vollständiger Artikel mit Übersetzungen, Eigenschaften und Preisregeln ein Vielfaches davon. Sinnvoll sind deshalb getrennte Paketgrößen je Datenart, ermittelt auf einer Testumgebung mit echten Datenmengen. Weil seit Version 6.5 alle Datensätze eines Aufrufs gemeinsam validiert und in einer Transaktion geschrieben werden (Shopware UPGRADE-6.5), hat die Paketgröße eine zweite Wirkung: Ein fehlerhafter Datensatz hält das ganze Paket auf. Kleinere Pakete machen jede Wiederholung billiger. So gehen Sie vor:

  1. Je Datenart einen typischen und einen besonders großen Datensatz aus dem ERP exportieren und ihre Größe als JSON messen.
  2. Die tatsächlichen Grenzen der Zielumgebung auslesen: Body-Grenze des Webservers, memory_limit und max_execution_time der PHP-FPM-Konfiguration.
  3. Mit einem kleinen Paket beginnen und die Größe stufenweise erhöhen, solange Antwortzeit und Speicherspitze deutlich unter den Grenzen bleiben.
  4. Den Wert mit Abstand zur Grenze festschreiben, damit Datensätze mit langen Beschreibungen oder vielen Übersetzungen das Paket nicht über die Grenze heben.
  5. Paketgröße, Laufzeit und abgelehnte Datensätze je Lauf protokollieren und nach Updates von Shopware oder Server erneut messen.

Indexierung über die Message Queue

Nach dem Schreiben ist die Arbeit für Shopware nicht erledigt. Abhängig von den geschriebenen Daten laufen Indexierungsprozesse, etwa für Suchbegriffe, Bestände oder SEO-Adressen. Ohne weitere Angabe indexiert Shopware synchron, also im selben Request. Für große Importe lässt sich die Indexierung über Header steuern und in einen asynchronen Hintergrundprozess verlegen (Shopware Admin-API-Referenz). Die Grundlagen von Warteschlangen, Producern und Consumern erklärt unser Beitrag zur ereignisgetriebenen Architektur mit Message Queues.

Header und WertWirkungEinsatz im Import
indexing-behavior: null (Voreinstellung)Indexierung synchron im Requestkleine Korrekturen, die sofort sichtbar sein sollen
indexing-behavior: use-queue-indexingIndexierung asynchron über die Message QueueRegelfall für Massenimporte, Worker arbeiten die Nachrichten ab
indexing-behavior: disable-indexingIndexierung vollständig ausgeschaltetnur mit geplanter Neuindexierung danach, etwa bei einer Erstbefüllung
indexing-skipüberspringt die genannten Indexer, kommagetrenntwenn ein Lauf bestimmte Daten nachweislich nicht berührt
indexing-onlyführt nur die genannten Indexer ausreiner Bestandsabgleich, etwa nur product.stock

Für Massenimporte ist use-queue-indexing der Regelfall. Der Request kehrt zurück, sobald die Daten geschrieben sind, und die Neuberechnung verteilt sich auf die Worker. disable-indexing ist ein Werkzeug für Sonderfälle: Wer es nutzt, muss die Indexierung danach selbst anstoßen, für einen vollständigen Durchlauf mit dal:refresh:index --use-queue. Shopware empfiehlt die Option --use-queue, weil sonst zu viele Produkte ohne Warteschlange indexiert werden müssten (Shopware-Dokumentation).

Wichtig ist der Satz, den die Dokumentation zur Message Queue der Planung der Worker voranstellt: Nachrichten zur Produktindexierung sind in der Regel langsam, andere Nachrichten werden sehr schnell verarbeitet (Shopware-Dokumentation). Teilen sich beide dieselbe Queue, warten zeitkritische Nachrichten, etwa Mails, sofern sie über die Queue laufen, hinter Tausenden Indexierungsaufträgen. Die Dokumentation rät deshalb, Nachrichten bei Bedarf auf einen anderen Transport zu leiten, um die Zahl der Worker je Nachrichtentyp zu begrenzen, Datenbanksperren zu vermeiden oder etwa den Mailversand zu priorisieren.

Indexierung auf einen eigenen Transport legen

Seit Shopware 6.6.4.0 und 6.5.12.0 lässt sich die Weiterleitung einzelner Nachrichtenklassen mit routing_overwrite überschreiben (Shopware-Dokumentation). Die Dokumentation zeigt das am Beispiel der EntityIndexingMessage, die auf einen eigenen Transport entity_indexing geht. Dieser Transport bekommt eigene Worker, deren Zahl Sie unabhängig vom übrigen Betrieb festlegen.
config/packages/*.yaml
# config/packages/framework.yaml
framework:
  messenger:
    transports:
      entity_indexing: "%env(MESSENGER_TRANSPORT_INDEXING_DSN)%"

# config/packages/shopware.yaml
shopware:
  messenger:
    routing_overwrite:
      'Shopware\Core\Framework\DataAbstractionLayer\Indexing\EntityIndexingMessage': entity_indexing

Wie viele Worker die Queue braucht

Eine allgemeine Empfehlung hält Shopware für schwierig: Die Zahl der Worker hängt von Menge und Art der Nachrichten ab; man soll die Queue beobachten und die Worker danach einstellen (Shopware-Dokumentation). Einen Anhaltspunkt liefert die Anleitung zur Einrichtung der Suche: Nach Erfahrung von Shopware sind bis zu drei Worker-Prozesse in Produktion normal und sinnvoll; wer mehr braucht, setzt einen eigenen Message-Broker ein, damit die Datenbank nicht zum Engpass wird (Shopware-Dokumentation).

Ebenso wichtig wie die Zahl ist, wo die Worker laufen. Ohne weitere Einrichtung verarbeitet Shopware Hintergrundaufgaben im Browser, solange jemand in der Administration angemeldet ist; für Produktivsysteme ist das nicht empfohlen (Shopware-Dokumentation). Ein nächtlicher Import mit use-queue-indexing würde dann so lange auf seine Indexierung warten, bis morgens jemand die Administration öffnet. In Produktion gehören die Worker als Konsolenprozesse unter eine Prozesssteuerung wie systemd. Das Beispiel der Dokumentation startet jeden Worker mit einer Laufzeitgrenze von 60 Sekunden und einer Speichergrenze von 512 MB; die Prozesssteuerung startet ihn danach neu (Shopware-Dokumentation).

Zwei Punkte gehen bei der Einrichtung leicht unter. Erstens braucht auch die Queue für fehlgeschlagene Nachrichten einen Worker, sonst bleiben diese Nachrichten liegen; Shopware wiederholt eine fehlgeschlagene Nachricht automatisch 3-mal und löscht sie danach (Shopware-Dokumentation). Zweitens lesen Worker neuen Code erst nach einem Neustart. Die Symfony-Dokumentation empfiehlt, Worker nicht unbegrenzt laufen zu lassen, etwa mit --limit=10 nach zehn Nachrichten zu beenden, und sie bei jedem Deploy neu zu starten (Symfony-Dokumentation). Und weil Konsole und PHP-FPM oft unterschiedliche php.ini-Dateien lesen (Shopware-Dokumentation), gelten für Worker andere Grenzen als für den Web-Request: Auf der Kommandozeile liegt die Voreinstellung der Ausführungszeit bei 0, also ohne Begrenzung (PHP-Handbuch). Der Füllstand der Queue gehört deshalb ins Monitoring der Schnittstellen. Ein Importlauf sieht damit so aus:

Ablauf eines Importlaufs über die Sync-API

  1. 1

    Delta ermitteln

    Das ERP liefert alle seit dem letzten erfolgreichen Lauf geänderten Preise, Bestände und Löschungen.

  2. 2

    Pakete bilden

    Die Middleware teilt die Änderungen nach Datenart in Pakete der gemessenen Größe und vergibt sprechende Operationsschlüssel.

  3. 3

    Senden

    Jedes Paket geht mit indexing-behavior: use-queue-indexing und sw-skip-trigger-flow an /api/_action/sync.

  4. 4

    Antwort auswerten

    Geschriebene IDs, notFound und Fehlerpfade werden je Paket protokolliert, abgelehnte Datensätze gesondert abgelegt.

  5. 5

    Queue abarbeiten

    Die Worker indexieren im Hintergrund; der Füllstand der Queue zeigt, wann die Änderungen im Shop sichtbar sind.

  6. 6

    Stichprobe prüfen

    Einige geänderte Artikel werden in der Storefront gegen das ERP geprüft, bevor der Lauf als erledigt gilt.

Fehler je Operation auswerten

Ältere Versionen ließen sich so aufrufen, dass einzelne Datensätze getrennt geschrieben wurden. Mit Version 6.5 entfiel dieses Verhalten: Alle Operationen und Datensätze eines Aufrufs werden als Sammlung validiert und in einer Transaktion geschrieben, die Header fail-on-error und single-operation gibt es nicht mehr (Shopware UPGRADE-6.5). Für den Import bedeutet das: Entweder werden alle Datensätze des Pakets geschrieben oder keiner.

Welche Datensätze das Paket aufgehalten haben, steht in der Fehlerantwort. Shopware sammelt die Validierungsfehler aller Datensätze, bevor es abbricht, und setzt für jeden Datensatz einen Pfad aus Operationsschlüssel und Position im Paket (Shopware-Quellcode). Ein Fehler unter /bestand-lauf-0412/17/ verweist also auf den Datensatz mit dem Index 17 in der Operation bestand-lauf-0412; die Zählung beginnt bei null. Die Middleware muss diesen Pfad auf den ERP-Datensatz zurückführen können, sonst bleibt nur die Suche von Hand. Bewährt haben sich diese Regeln:

  • Abgelehnte Datensätze in eine Ablage für die Fachabteilung schreiben und das restliche Paket ohne sie erneut senden.
  • Bei Status 413 das Paket teilen und die Paketgröße für diese Datenart senken, statt den Lauf abzubrechen.
  • Bei Zeitüberschreitung oder Verbindungsabbruch das Paket unverändert wiederholen; dank Upsert mit festen IDs entstehen dabei keine Dubletten.
  • notFound aus Löschoperationen protokollieren: Ein im Shop fehlender Datensatz deutet oft auf eine Lücke im Mapping.
  • Je Lauf Zahl der Pakete, geschriebene IDs, abgelehnte Datensätze und Dauer festhalten, damit Ausreißer auffallen.

Wie Wiederholungen sauber begrenzt werden, beschreiben die Beiträge zu Idempotenz und Retry-Strategien und zur Fehlerbehandlung in Schnittstellen. Für die Sync-API gilt zusätzlich: Ein Paket, das an einem einzelnen Datensatz scheitert, darf nicht in einer Schleife wiederholt werden, bevor dieser Datensatz herausgenommen ist. Welche Fehlerantworten Ihre Middleware erwartet und wie sie darauf reagiert, gehört in die Beschreibung der Schnittstelle.

Delta statt Vollabgleich

Der größte Hebel liegt vor dem ersten Paket, in der Frage, was überhaupt übertragen wird. Ein Vollabgleich schickt jede Nacht das gesamte Sortiment, auch die Artikel, an denen sich nichts geändert hat. Jeder dieser Datensätze wird geschrieben und löst Indexierung aus. Ein Delta-Abgleich überträgt nur, was sich seit dem letzten erfolgreichen Lauf geändert hat. Dafür braucht das ERP eine verlässliche Änderungsmarke je Datensatz, etwa einen Zeitstempel oder ein Änderungsprotokoll, und die Middleware merkt sich den Stand des letzten erfolgreich abgeschlossenen Laufs.

Zwei Punkte entscheiden darüber, ob ein Delta-Abgleich verlässlich ist. Löschungen müssen als eigene Ereignisse aus dem ERP kommen, denn ein gelöschter Artikel taucht in keiner Änderungsliste mehr auf. Und die Datenhoheit muss je Feld geklärt sein: Pflegt das Marketing Beschreibungen im Shop, darf der Import dieses Feld nicht überschreiben. Wie solche Konflikte zu lösen sind, behandelt der Beitrag zur bidirektionalen Synchronisation. Preise und Bestände laufen sinnvollerweise als eigene, kleine Deltas getrennt von den Stammdaten, wie es auch die Beiträge zur Preissynchronisation im B2B und zur Bestandssynchronisation bei mehreren Lagern beschreiben.

Ein gelegentlicher Vollabgleich bleibt trotzdem sinnvoll, aber als Kontrolle: Er vergleicht Prüfsummen oder Stichproben zwischen ERP und Shop und schreibt nur die Abweichungen. Gelegt wird er in ein ruhiges Zeitfenster, nicht in die Woche vor einer Aktion. Der Unterschied im Überblick:

MerkmalVollabgleichDelta-Abgleich
Übertragene Datensätzegesamtes Sortiment je Laufnur Änderungen seit dem letzten Lauf
Indexierungslastfür jeden übertragenen Artikelnur für geänderte Artikel
Gelöschte Artikelfallen durch ihr Fehlen aufbrauchen eigene Löschereignisse aus dem ERP
Laufzeitwächst mit dem Sortimentwächst mit der Zahl der Änderungen
Rolle im BetriebKontrolle in ruhigen ZeitfensternRegelbetrieb, auch tagsüber

Den Import vor das Aktionsfenster legen

Für das Aktionsgeschäft heißt das: Der große Import gehört vor das Aktionsfenster, nicht hinein. Sets, Stammdaten und Bestände für Aktionsartikel sollten einige Tage vorher im Shop stehen, damit Indexierung, Caches und Kontrollen abgeschlossen sind, bevor der Andrang beginnt. Preise, die erst ab einem Stichtag gelten, lassen sich vorab anlegen und an eine Regel mit Zeitraum binden, statt sie in der Nacht vor der Aktion zu importieren. Während der Aktionstage laufen nur noch kleine Deltas für Bestände. Wie Sie nächtliche Massenjobs aus dem Aktionsfenster nehmen und den Bestellfluss Richtung ERP absichern, beschreibt der Beitrag zur Bestellspitze in der Black Week.

Auch die übrigen Hintergrundjobs gehören in die Planung. Die Erzeugung der Sitemap kann als geplante Aufgabe die Queue für längere Zeit blockieren; seit Version 6.7.1.0 lässt sie sich aus der Queue nehmen und per Cronjob zu ruhigen Zeiten starten (Shopware-Dokumentation). Bei großem Sortiment oder hoher Änderungsfrequenz kann der Indexer für dynamische Produktgruppen zum Engpass werden; ab Version 6.6.10.0 lässt er sich abschalten, allerdings mit Nebenwirkungen auf Kategorieseiten und Regeln (Shopware-Dokumentation). Solche Eingriffe sollten vor der Aktion getestet sein, nicht erst in ihrer ersten Nacht. Eine sinnvolle Reihenfolge für die Wochen davor:

  1. Paketgrößen und Zahl der Worker auf der Testumgebung mit den Datenmengen der Aktion messen.
  2. Die Indexierung auf einen eigenen Transport legen und den Füllstand der Queue ins Monitoring aufnehmen.
  3. Sets, Stammdaten und vorab angelegte Aktionspreise importieren und stichprobenartig in der Storefront prüfen.
  4. Vollabgleiche und andere große Jobs für die Aktionstage aussetzen.
  5. Während der Aktion nur Bestands- und Preisdeltas fahren und den Füllstand der Queue beobachten.

Ob Ihre bestehende Anbindung schon so arbeitet, zeigt ein Blick auf drei Dinge: wie viele Aufrufe ein Lauf erzeugt, wo die Indexierung stattfindet und ob abgelehnte Datensätze nachvollziehbar abgelegt werden. Wir prüfen Importe im Rahmen unserer API-Entwicklung und bauen sie, wo es mehrere Systeme zu verbinden gilt, als Teil einer Middleware. Für eine erste Einschätzung erreichen Sie uns über die Kontaktseite.

Ein Paket, eine Queue, ein Delta

Ein schneller Import hängt weniger an größerer Hardware als an drei Entscheidungen: Daten gebündelt über die Sync-API senden, die Indexierung über die Message Queue mit eigenen Workern abarbeiten und nur übertragen, was sich geändert hat. Wer diese drei Stellschrauben gemessen einstellt, hält Shop und Import auch vor dem Aktionsgeschäft auseinander.
Dieser Artikel basiert auf Daten aus: Shopware Admin-API-Referenz, Seite Bulk Payloads; Shopware-Dokumentation, Seiten Message Queue, Hosting, Einrichtung der Suche und Performance-Tweaks; Shopware Release Notes 6.7.11.0; Shopware UPGRADE-6.5; Shopware-Quellcode (SyncService, EntityWriter, ApiRequestContextResolver); nginx-Dokumentation, Modul ngx_http_core_module; PHP-Handbuch, Konfigurationsoptionen; RFC 9110 der IETF; Symfony-Dokumentation, Messenger.

Verwandte Artikel

APIs, Middleware & Architektur

Schnittstellen dokumentieren: OpenAPI statt Wissen im Kopf

Shop-ERP-Schnittstellen mit OpenAPI beschreiben: Felder, Fehlercodes, Beispiele und Rechte, die Beschreibung als Vertrag und das Übergabepaket beim Wechsel.

18 Min. Lesezeit
Shop-Integration & Prozesse

DATEV Rechnungsdatenservice 2.0 endet: Datenweg umstellen

DATEV stellt den Rechnungsdatenservice 2.0 zum 31.12.2026 ein. So prüfen Shops und Wawi-Anbindungen, ob sie betroffen sind, und stellen den Belegweg um.

19 Min. Lesezeit
ERP- & Warenwirtschaft

Bestellspitze zur Black Week: ERP-Schnittstelle vorbereiten

Black Week 2026: Auftragsfluss zwischen Shop und ERP vorbereiten – Rückstau messen, Nachtjobs verschieben, Warteschlange mit Alarm, Änderungsstopp, Notweg.

18 Min. Lesezeit