Projekt

Laravel Ingest: Ein robustes ETL-Framework

2025-02-05
Laravel Ingest: Ein robustes ETL-Framework

Als mein erstes großes Open-Source-Projekt habe ich Laravel Ingest entwickelt – ein robustes ETL (Extract, Transform, Load) Framework, das speziell dafür entwickelt wurde, Datenimporte in PHP-Anwendungen zu vereinfachen und zu stabilisieren.

⚡ Das Problem

Datenimporte (CSV, Excel, JSON) führen oft zu fragilen Skripten, die manuell über Zeilen iterieren, Daten validieren und bei großen Dateien schnell an Speichergrenzen (Memory Leaks) stoßen.

🛠 Die Lösung

Laravel Ingest ersetzt prozedurale Skripte durch eine deklarative Fluent API. Das Framework übernimmt die schwere Arbeit im Hintergrund: Streaming, Chunking, Queueing, Validierung und Fehlerbehandlung.

Hauptfeatures

  • ♾️ Unendliche Skalierbarkeit: Nutzt PHP Generators und Laravel Queues, um Dateien jeder Größe mit konstantem Speicherverbrauch zu verarbeiten.
  • 📝 Deklarative Syntax: Definiere was importiert werden soll, nicht wie.
  • 🔗 Auto-Relations: Löst automatisch BelongsTo und BelongsToMany Beziehungen auf (z.B. Suche nach IDs anhand von Namen).
  • 🛡️ Fehlerbehandlung: Trackt jede fehlgeschlagene Zeile und generiert eine CSV-Datei, die nur die Fehler enthält – ideal für Korrekturen durch den Endnutzer.
  • 🔌 API & CLI Ready: Bringt automatisch REST-Endpunkte und Artisan Commands mit.

💻 Code Beispiel

Statt hunderten Zeilen Controller-Code wird ein Import in einer einzigen Konfigurationsklasse definiert:

class ProductImporter implements IngestDefinition
{
    public function getConfig(): IngestConfig
    {
        return IngestConfig::for(Product::class)
            // Unterstützt Uploads, S3, FTP, URLs, etc.
            ->fromSource(SourceType::UPLOAD)
 
            // Intelligente Duplikat-Erkennung
            ->keyedBy('sku')
            ->onDuplicate(DuplicateStrategy::UPDATE_IF_NEWER)
 
            // Mapping & Transformation
            ->map('Produkt Name', 'name')
            ->mapAndTransform('Preis', 'price_cents', fn($val) => $val * 100)
 
            // Automatische Beziehungsauflösung
            ->relate('Kategorie', 'category', Category::class, 'name', createIfMissing: true)
 
            // Zeilenbasierte Validierung
            ->validate(['sku' => 'required|string']);
    }
}

🏗 Architektur & Technik

Bei der Entwicklung habe ich besonderen Wert auf saubere Architektur gelegt:

  1. Speichermanagement: Durch die Implementierung von SourceHandler Interfaces und striktem Streaming werden Dateien speichereffizient verarbeitet.
  2. Design Patterns: Einsatz von Factory Patterns für verschiedene Datenquellen und DTOs für den Datentransfer.
  3. Developer Experience (DX): Features wie "Dry Runs" (Simulation ohne DB-Schreibvorgänge) und Events erleichtern die Integration in Frontend-Applikationen.

✅ Qualitätssicherung

Das Projekt folgt strikten Standards:

  • 100% Test Coverage: Getestet mit Pest PHP.
  • Statische Analyse: Larastan/PHPStan Level 5.
  • CI/CD: Automatisierte GitHub Actions Pipeline für Tests, Linting und Publishing.

Dokumentation ansehen | Auf GitHub ansehen