90% van de integratieproblemen die wij bij klanten zien, zit niet in de connectie. Het zit in de transformatie. Het ERP spuugt XML uit, de webshop-API verwacht JSON, en daartussen…
Data transformatie in Alumio: van XML naar JSON en terug
90% van de integratieproblemen die wij bij klanten zien, zit niet in de connectie. Het zit in de transformatie. Het ERP spuugt XML uit, de webshop-API verwacht JSON, en daartussen moet iemand bepalen dat hetzelfde is als sku. Die laag onderschat bijna iedereen.
Alumio is een iPaaS dat precies voor die laag is gebouwd. Geen losse scripts, maar een visuele transformatie-pipeline met versiebeheer en logging. In dit artikel duiken we diep in hoe transformatie in Alumio werkt: transformers, templating, veld-mapping, validatie en de edge cases die je pas tegenkomt in productie.
Waarom XML-naar-JSON geen kopieer-actie is
ERP-systemen als Exact, AFAS en Microsoft Dynamics leveren data vaak als XML. Webshops draaien op REST-API's die JSON spreken. De naïeve aanname: je zet het ene format om in het andere en klaar.
In de praktijk botsen drie werelden:
- Datatypes. XML kent geen types. Alles is string.
is tekst, maar je API wil een integer0050 50. - Structuur. XML is hiërarchisch en kent attributen. JSON kent arrays en objecten, geen attributen.
- Conventies. ERP gebruikt
ArtikelNr, de APIsku. ERP levert prijzen inclusief BTW, je shop verwacht exclusief.
Transformatie is dus geen format-conversie. Het is een vertaalslag tussen twee datamodellen die elkaars taal niet spreken. Daar zit het echte werk.
De transformatie-pipeline in Alumio
Alumio splitst elke integratie op in losse, herbruikbare stappen. Data stroomt door een keten:
- Subscriber haalt de data binnen (een API-call naar het ERP, een webhook, een bestand).
- Inbound transformer zet het binnenkomende format om naar een interne, genormaliseerde structuur.
- Storage / entity bewaart de genormaliseerde data tijdelijk.
- Outbound transformer zet die structuur om naar het format dat de bestemming verwacht.
- Publisher levert het resultaat af bij de webshop-API.
Het cruciale inzicht: je vertaalt niet rechtstreeks van XML naar JSON. Je vertaalt eerst naar een intern model, en dan naar JSON. Daardoor kun je één ERP koppelen aan meerdere webshops zonder de transformatie te dupliceren.
Meer over hoe deze architectuur zich verhoudt tot maatwerk lees je in Alumio iPaaS uitgelegd.
XML inlezen: van hiërarchie naar plat model
XML-parsing is in Alumio de eerste stap waar het misgaat als je niet oplet. Neem deze ERP-output:
<Product id="A-1042">
<Naam>Bureaustoel Ergo</Naam>
<Prijs valuta="EUR">149.00</Prijs>
<Voorraad>50</Voorraad>
<Categorieen>
<Categorie>Meubels</Categorie>
<Categorie>Kantoor</Categorie>
</Categorieen>
</Product>
Twee dingen vragen aandacht. De id is een attribuut, geen element. En Categorieen bevat herhalende elementen die je naar een array wilt mappen.
Alumio's XML-decoder zet dit om naar een interne structuur waarin attributen een eigen sleutel krijgen (vaak met een prefix) en herhalende elementen een array worden. Je veld-mapping verwijst dan naar paden als Product.@id voor het attribuut en Product.Categorieen.Categorie voor de lijst.
Let op die laatste. Bij één categorie levert XML geen array maar een los element. Bij twee of meer wel. Dit is de klassieke valkuil. Je mapping werkt prima in de test en breekt in productie bij een product met één categorie.
Veld-mapping: de kern van de transformatie
Veld-mapping in Alumio doe je met transformers. Dit zijn configureerbare bewerkingen die je achter elkaar zet. De meest gebruikte:
| Transformer | Doel | Voorbeeld |
|---|---|---|
| Set field | Veld kopiëren of hernoemen | ArtikelNr → sku |
| Cast | Type omzetten | string "50" → integer 50 |
| Replace | Tekst vervangen | , → . in prijzen |
| Calculate | Rekenen | prijs incl. → excl. BTW |
| Map values | Waarden vertalen | J/N → true/false |
| Conditional | Voorwaardelijk veld zetten | alleen als voorraad > 0 |
Een typische product-mapping ziet er dan zo uit:
Product.@id→sku(Set field)Product.Naam→name(Set field)Product.Prijs→price(Cast naar float, daarna Calculate/ 1.21)Product.Voorraad→stock(Cast naar integer)Product.Categorieen.Categorie→categories(array behouden)
De volgorde van transformers is belangrijk. Cast eerst naar een numeriek type voordat je gaat rekenen. Doe je het andersom, dan rekent Alumio op een string en krijg je rare uitkomsten of een harde fout.
Templating: complexe JSON opbouwen
Niet elke transformatie is een simpele veld-naar-veld-mapping. Soms moet je een geneste JSON-structuur opbouwen die niet één-op-één in de bron staat. Daarvoor gebruikt Alumio Twig-templating.
Stel je wilt een Shopify-product opbouwen met een vaste structuur:
{
"product": {
"title": "{{ data.name }}",
"variants": [
{
"sku": "{{ data.sku }}",
"price": "{{ data.price | number_format(2, '.', '') }}",
"inventory_quantity": {{ data.stock }}
}
],
"status": "{% if data.stock > 0 %}active{% else %}draft{% endif %}"
}
}
Twig geeft je logica binnen de transformatie: conditionals, loops, filters en formattering. De number_format-filter forceert hier twee decimalen met een punt als scheidingsteken. De if-statement zet een product op draft zodra de voorraad nul is.
Onze regel: gebruik Twig voor structuur en logica, gebruik transformers voor losse veldbewerkingen. Stop niet alles in één gigantische Twig-template. Dat wordt onleesbaar en onhoudbaar zodra een collega het overneemt.
En weer terug: JSON naar XML
De omgekeerde richting komt net zo vaak voor. Een bestelling uit de webshop (JSON) moet als XML het ERP in. Hier draaien de problemen om.
Waar je bij XML-naar-JSON arrays moet herkennen, moet je ze bij JSON-naar-XML weer uitvouwen naar herhalende elementen:
{ "order": { "lines": [
{ "sku": "A-1042", "qty": 2 },
{ "sku": "B-2010", "qty": 1 }
]}}
wordt:
<Order>
<Regels>
<Regel><ArtikelNr>A-1042</ArtikelNr><Aantal>2</Aantal></Regel>
<Regel><ArtikelNr>B-2010</ArtikelNr><Aantal>1</Aantal></Regel>
</Regels>
</Order>
In Alumio loop je met een Twig for-loop over de lines-array en genereer je per regel een -element. Twee aandachtspunten:
- Numerieke types worden weer string. XML kent geen types, dus dat is geen probleem. Maar je ERP kan wel eisen dat
zonder decimalen komt. Cast en formatteer expliciet. - Speciale tekens. Een productnaam met
&of<breekt je XML als je niet escaped. Alumio's XML-encoder doet dit, maar controleer het altijd met echte productdata uit het ERP.
Validatie: faal vroeg, faal duidelijk
Een transformatie die foute data stilletjes doorlaat, is erger dan een transformatie die crasht. Wij bouwen validatie altijd in vóór de publisher.
Alumio biedt hiervoor verschillende mechanismen:
- Required-checks. Mist
sku? Dan stopt de flow en logt Alumio welk veld ontbreekt. - Type-validatie. Een prijs die geen geldig getal is, wordt afgevangen voordat hij de API bereikt.
- Conditional skip. Producten zonder geldige categorie kun je overslaan in plaats van de hele batch te laten falen.
De logging is het verschil tussen vijf minuten en een halve dag debuggen. Alumio bewaart per transformatie de input en output. Wanneer een mapping fout gaat, zie je exact welke binnenkomende waarde het probleem veroorzaakte. Dat scheelt giswerk.
Onze aanpak bij klanten: liever 998 van de 1000 producten correct doorzetten en 2 met een nette foutmelding parkeren, dan 1000 producten waarvan je niet weet welke kapot zijn.
De edge cases die je in productie tegenkomt
De demo werkt altijd. Productie is waar het breekt. Dit zijn de transformatie-problemen die wij keer op keer zien tussen ERP-XML en API-JSON:
- Lege elementen.
is geennull, het is een lege string. Een Cast naar float faalt. Vang lege waarden eerst af. - Single vs. multiple. Eén categorie = element, meerdere = array. Forceer altijd een array in je mapping.
- Encoding. ERP-export in ISO-8859-1, API verwacht UTF-8. Accenttekens worden mojibake. Zet encoding expliciet.
- Decimaal-komma. Nederlandse ERP-exports gebruiken soms
149,00. JSON-getallen eisen een punt. Replace vóór Cast. - Timezones. Een orderdatum zonder timezone-info wordt verkeerd geïnterpreteerd. Normaliseer naar ISO 8601 met expliciete offset.
- Booleans als tekst.
J/N,1/0,Ja/Nee: elk ERP doet het anders. Map values is hier je vriend.
Geen enkele hiervan is moeilijk. Maar ze stapelen op. Een productflow van 30 velden heeft al snel 10 transformers die elk een edge case afvangen.
Wanneer Alumio niet de juiste keuze is
Wij verkopen geen tools, we verkopen werkende koppelingen. Eerlijk: Alumio is niet altijd de beste oplossing.
Heb je één simpele koppeling tussen twee systemen die nooit verandert? Dan is een Laravel maatwerk-integratie vaak goedkoper en sneller. De kracht van Alumio zit in meerdere koppelingen, herbruikbare transformaties en het inzicht dat de logging je geeft.
Bij meer dan twee of drie systemen, of bij koppelingen die regelmatig wijzigen, kantelt de afweging richting iPaaS. Dan win je de licentiekosten terug op onderhoud en debugtijd. Die afweging maken we graag samen, lees ook Alumio vs. custom integraties.
Twijfel je welke kant op voor jouw Magento- of Shopify-omgeving? Neem contact op en we kijken mee naar je datamodel voordat je een tool kiest.
Veelgestelde vragen
Kan Alumio overweg met grote XML-bestanden uit mijn ERP?
Ja. Alumio verwerkt data in batches en streamt grote bestanden in plaats van alles in geheugen te laden. Bij zeer grote exports (tienduizenden producten) splits je de subscriber op in pagina's of deelbestanden. Dat houdt de transformatie snel en voorkomt timeouts richting de webshop-API.
Moet ik kunnen programmeren om transformaties in Alumio te bouwen?
Voor het grootste deel niet. Veld-mapping en de standaard-transformers configureer je visueel zonder code. Pas bij complexe geneste structuren of conditionele logica heb je Twig-templating nodig, en dat is geen volwaardige programmeertaal. Wij bouwen de basis vaak zo op dat jouw team zelf kleine wijzigingen kan doen.
Wat gebeurt er als een transformatie faalt op één product?
Dat bepaal je zelf in de configuratie. Je kunt de hele batch laten stoppen, of het foute item parkeren en de rest doorzetten. Wij adviseren bijna altijd het tweede, met een duidelijke foutmelding in de logging. Zo blokkeert één kapot product nooit je hele voorraad-sync.
Hoe ga ik om met prijzen inclusief en exclusief BTW?
Met een Calculate-transformer. Levert je ERP inclusief BTW en wil je shop exclusief, dan deel je door 1,21 (of het juiste tarief). Cast de waarde eerst naar een numeriek type en rond daarna af op het aantal decimalen dat je API verwacht. Bouw verschillende BTW-tarieven in met een Map values op de tariefcode.
Kan ik dezelfde transformatie hergebruiken voor meerdere webshops?
Ja, en dat is precies de winst van de pipeline-architectuur. Omdat je eerst naar een intern model vertaalt, hoef je de inbound-transformatie maar één keer te bouwen. Per webshop voeg je alleen een outbound-transformatie toe. Eén ERP-koppeling voedt zo meerdere shops zonder dubbel werk.

Geschreven door Ruthger Idema
15+ jaar ervaring in e-commerce development. Gespecialiseerd in Magento, Shopify en Laravel maatwerk.
Meer over ons team →