Wir haben die Produktdaten-API fĂŒr Migros 10 Jahre lang entwickelt und gepflegt â mit vollem Engagement fĂŒr agile Entwicklung. Die erste Version ging nach nur sechs Monaten live, danach haben wir kontinuierlich neue Features hinzugefĂŒgt und uns an verĂ€nderte Anforderungen sowie neue Drittanbieter-Systeme angepasst.
Nach 10 Jahren hat Migros ein internes Team aufgebaut, um die Weiterentwicklung selbst zu ĂŒbernehmen. In den letzten zwei Jahren der Zusammenarbeit arbeiteten unsere Entwickler*innen eng mit dem wachsenden internen Team der Migros zusammen und ĂŒbertrugen schrittweise das Wissen und die Verantwortung. Bis 2024 hat Migros das Projekt vollstĂ€ndig ĂŒbernommen.
Die Anwendung ist ein zentrales System, das Echtzeitzugriff auf alle Produktdaten ermöglicht. Sie sammelt Informationen aus vielen GeschĂ€ftsapplikationen â von SAP-Systemen und REST-APIs bis hin zu CSV-Dateien. Die gesammelten Daten werden gefiltert, aufbereitet und in einem Elasticsearch-Cluster gespeichert. Manche Anwendungen fragen Daten in Echtzeit per REST ab. Andere abonnieren den unternehmensweiten Message Bus, um Updates in ihren eigenen Systemen zu synchronisieren.

Strategie
Von Anfang an hatten wir eine klare Architektur-Vision fĂŒr den Aufbau der API. Wir hielten die Codebasis dank gezielter Refactorings modern und gut wartbar. Moderne Programmierpraktiken spielten dabei eine zentrale Rolle:
- Unit- und Funktionstests: Ohne sie wÀre es schwierig gewesen, Code sicher zu refaktorisieren.
- PHPStan: Ein statischer Analysator zur Erkennung potenzieller Fehler und unlogischer Codekonstruktionen.
- Typisierte Variablen: Seit PHP 7 ermöglicht dies eine robustere Codebasis.
- Rector: Automatisierte Code-Refaktorierung zur Anpassung an moderne Best Practices.
- PHP-CS-Fixer: Automatisches Code-Style-Formatieren fĂŒr einheitliche Optik.
Diese konsequente QualitĂ€tsstrategie wurde auch vom Kunden mitgetragen. Ich erinnere mich an eine wichtige Situation in einem frĂŒhen Backlog-Refinement-Meeting: Wir diskutierten, ob eine Story mit einer schnellen Lösung umgesetzt oder ein Refactoring durchgefĂŒhrt werden sollte. Der Product Owner entschied sich klar fĂŒr das Refactoring, um die langfristige Wartbarkeit der Anwendung sicherzustellen. Dieses Mindset prĂ€gte das gesamte Projekt.
Durch kontinuierliches Refactoring blieb der Code logisch strukturiert, konsistent und leicht verstÀndlich. Dies verhinderte Redundanzen, da Entwickler*innen existierenden Code leichter finden können, anstatt Funktionen doppelt zu implementieren.
In langfristigen Projekten verbringen Entwickler*innen weit mehr Zeit damit, Code zu lesen und zu verstehen, als neuen Code zu schreiben. Deshalb ist es essenziell, bestehendem Code die gleiche Aufmerksamkeit zu schenken wie neuem.
Tools
Sehen wir uns einige der Tools an, die wir in dieser sich stÀndig weiterentwickelnden Umgebung genutzt haben.
Testing
Legacy Code ist einfach Code ohne Tests.âMichael C. Feathers
Automatisierte Tests wurden von Anfang an implementiert â der beste Zeitpunkt, um sicherzustellen, dass die QualitĂ€t des Fundaments hoch bleibt. SpĂ€tere TesteinfĂŒhrungen sind oft aufwĂ€ndig und werden daher selten vollstĂ€ndig umgesetzt.
Wir nutzten verschiedene Testebenen:
- PHPUnit fĂŒr Unit-Tests
- PHPUnit fĂŒr funktionale Tests (z. B. Datenbank-Repositories oder API-Endpunkte)
- Behat fĂŒr End-to-End-Tests (leistungsfĂ€hig, aber fehleranfĂ€llig wegen realer Daten)
ZusĂ€tzlich verwendeten wir den statischen Analysator PHPStan. Dieses Tool kombiniert Code mit Dokumentationskommentaren und erkennt ganze Fehlerkategorien, bevor der Code ĂŒberhaupt ausgefĂŒhrt wird. Es trĂ€gt dazu bei, klareren Code und bessere Dokumentationen zu schreiben.
Dokumentation
Wir dokumentierten das Projekt auf mehreren Ebenen:
- Ein Wiki fĂŒr Konzepte und GeschĂ€ftsentscheidungen, gemeinsam gepflegt von Product Ownern, Entwickler*innen und Stakeholdern.
- Interaktive API-Dokumentation, generiert aus dem Code und den Kommentaren.
- Dokumentationskommentare im Code, ergÀnzt durch README-Dateien und zusÀtzliche Dokumente direkt im Git-Repository.
- ADR (Architecture Decision Record) zur Nachverfolgung von Architekturentscheidungen und zur Abstimmung im Entwickler*innen-Team.
Wir nutzten ausserdem einen automatischen Code-Style-Fixer. Einheitliche Formatierung reduziert kognitive Belastung und verhindert unnötige FormatierungsĂ€nderungen in funktionalen Code-Ănderungen. Unser Toolset basierte auf Symfony-Standards â nicht, weil der Stil perfekt ist, sondern weil Konsistenz wichtiger ist als der Stil selbst.