Lighthouse GraphQL für Laravel: Praxiseinstieg
AI generated
{ }
type
GraphQL · Laravel · Eloquent
Lighthouse GraphQL für Laravel
Praxiseinstieg ohne Resolver-Boilerplate

Lighthouse bindet GraphQL-Schemas direkt an Eloquent-Modelle, ohne dass für jedes Feld ein eigener Resolver geschrieben werden muss. Statt PHP-Klassen zu bauen, beschreiben SDL-Direktiven wie @hasMany, @paginate und @guard die komplette Anbindung an Datenbank, Beziehungen und Middleware. Wer bereits Laravel-Konventionen kennt, findet sich in Lighthouse schnell zurecht.

18 Min. Lesezeit Lighthouse · Laravel · Eloquent · Subscriptions graphql-php · PHP 8.x · Artisan

1. Was ist Lighthouse und warum GraphQL in Laravel

Lighthouse ist das führende GraphQL-Paket für Laravel und baut intern auf graphql-php von Webonyx auf. Der zentrale Unterschied zu einer manuellen graphql-php-Integration: Lighthouse verknüpft das Schema per SDL-Direktiven direkt mit Eloquent-Modellen, Query-Buildern und Laravel-Middleware, statt für jedes Feld einen eigenen Resolver zu verlangen. Ein einfaches Feld wie products: [Product!]! @all lädt automatisch alle Produkte aus der Datenbank, ganz ohne PHP-Code für den Resolver.

Für Laravel-Teams, die bereits mit Eloquent, Form Requests und Policies arbeiten, senkt Lighthouse die Einstiegshürde für GraphQL erheblich, weil sich fast alle bekannten Laravel-Konzepte direkt im Schema wiederverwenden lassen. Der Trade-off: Man verliert etwas an Low-Level-Kontrolle gegenüber reinem graphql-php, gewinnt dafür massiv an Entwicklungsgeschwindigkeit bei typischen CRUD-lastigen APIs, wie sie in vielen Laravel-Projekten den Großteil der Endpunkte ausmachen.

2. Installation und Grundkonfiguration

Die Installation von Lighthouse erfolgt über Composer, gefolgt vom Publizieren der Standardkonfiguration und eines initialen Schema-Grundgerüsts per Artisan-Befehl. Direkt nach der Installation existiert bereits ein funktionierender /graphql-Endpunkt mit einem Minimal-Schema, das sich schrittweise erweitern lässt. Für die lokale Entwicklung empfiehlt sich zusätzlich laravel-graphql-playground oder Nuwave's eigene GraphiQL-Integration, um Queries direkt im Browser zu testen.

Wichtig ist die Konfigurationsdatei config/lighthouse.php: Hier werden Pfad zum Schema, aktivierte Middleware-Gruppen und der Namespace für benutzerdefinierte Resolver-Klassen festgelegt. Bei bestehenden Laravel-APIs, die bereits REST-Routen nutzen, kann Lighthouse parallel betrieben werden, GraphQL und REST teilen sich problemlos dieselbe Datenbank und dieselben Eloquent-Modelle.


# Install Lighthouse and publish the base configuration
composer require nuwave/lighthouse
php artisan vendor:publish --tag=lighthouse-schema
php artisan vendor:publish --tag=lighthouse-config

# Optional: interactive GraphQL IDE for local development
composer require mll-lab/laravel-graphiql --dev
php artisan vendor:publish --tag=graphiql-config

# Verify the endpoint responds
php artisan serve
curl -X POST http://localhost:8000/graphql \
  -H "Content-Type: application/json" \
  -d '{"query": "{ __typename }"}'

3. Schema mit SDL-Direktiven definieren

Das Herzstück von Lighthouse ist die zentrale Datei graphql/schema.graphql, die normale GraphQL-SDL mit zusätzlichen, Lighthouse-eigenen Direktiven kombiniert. Direktiven wie @all, @find, @paginate und @orderBy übersetzen Standard-Feldabfragen direkt in Eloquent-Query-Aufrufe, ohne dass Entwickler die zugrunde liegende SQL-Logik selbst schreiben. Für komplexere Fälle, die sich nicht über eine Direktive abbilden lassen, erlaubt @field das Verweisen auf eine eigene PHP-Resolver-Klasse.

Diese Kombination aus deklarativem SDL und punktuellem PHP-Code ist der eigentliche Kern von Lighthouse: Für achtzig Prozent der Felder, typische Auflistungen, Detailabfragen und einfache Filter, reicht eine einzeilige Direktive. Nur für fachlich komplexe Logik, etwa eine Preisberechnung mit mehreren Rabattregeln, wird ein eigener Resolver nötig. Das hält Schema-Dateien deutlich kompakter als vergleichbare Schema-First-Setups mit reinem graphql-php.


# schema.graphql — Lighthouse directives bind fields to Eloquent directly
type Product {
  id: ID!
  sku: String!
  name: String!
  price: Float!
  category: Category! @belongsTo
  reviews: [Review!]! @hasMany
}

type Category {
  id: ID!
  name: String!
  products: [Product!]! @hasMany
}

type Query {
  products(name: String @where(operator: "like")): [Product!]! @paginate(defaultCount: 20)
  product(sku: String! @eq): Product @find
}

4. Eloquent-Modelle direkt im Schema nutzen

Lighthouse erkennt Beziehungen zwischen GraphQL-Typen und Eloquent-Modellen anhand von Namenskonventionen, ähnlich wie Eloquent selbst Beziehungen zwischen Tabellen erkennt. Direktiven wie @belongsTo, @hasMany und @belongsToMany spiegeln direkt die entsprechenden Eloquent-Relationship-Methoden wider und übernehmen automatisch deren Eager-Loading-Verhalten, sofern korrekt mit Batchloading kombiniert. Für Felder, die nicht direkt einer Datenbankspalte entsprechen, etwa ein berechnetes discountedPrice, greift Lighthouse automatisch auf eine gleichnamige Accessor-Methode im Eloquent-Modell zurück.

Diese enge Kopplung an Eloquent ist zugleich Stärke und Grenze von Lighthouse: Für Domänen, die sauber auf Eloquent-Modelle abbildbar sind, wie klassische E-Commerce- oder CMS-Strukturen, entfällt viel Boilerplate. Für stark von der Datenbankstruktur abweichende GraphQL-Schemas, etwa aggregierte Reporting-Views über mehrere Tabellen hinweg, stößt die direkte Direktiven-Bindung an Grenzen, dort sind eigene Resolver-Klassen die bessere Wahl.

5. Mutations und Validierung mit Lighthouse

Mutations werden in Lighthouse analog zu Queries per SDL definiert, meist kombiniert mit @create, @update oder einem eigenen Resolver für komplexere Schreibvorgänge. Für Input-Validierung nutzt Lighthouse die aus Laravel bekannten Validierungsregeln direkt als Argument-Direktive @rules, sodass Regeln wie required, min oder eigene Custom-Rule-Klassen wiederverwendet werden können, ohne separate GraphQL-spezifische Validierungslogik zu pflegen.

Schlägt die Validierung fehl, gibt Lighthouse automatisch strukturierte Fehler im GraphQL-errors-Array zurück, inklusive eines validation-Objekts in den extensions, das pro Feld die konkreten Fehlermeldungen auflistet. Frontend-Clients können damit Formularfehler genauso granular anzeigen wie bei einer klassischen Laravel-Form-Request-Validierung über REST, ein wichtiger Pluspunkt gegenüber selbstgebauten Validierungslösungen in reinem graphql-php.


# schema.graphql — mutation with Laravel validation rules reused as-is
type Mutation {
  createReview(
    productId: ID! @rules(apply: ["required", "exists:products,id"])
    rating: Int! @rules(apply: ["required", "integer", "min:1", "max:5"])
    comment: String @rules(apply: ["nullable", "max:2000"])
  ): Review! @create
}

6. Authentifizierung und Autorisierung

Für Authentifizierung nutzt Lighthouse dieselben Guards, die auch für REST-Routen in Laravel konfiguriert sind, meist Sanctum oder Passport für API-Tokens. Die Direktive @guard schützt einzelne Felder oder ganze Mutation-Typen und lehnt nicht authentifizierte Requests automatisch mit einem passenden GraphQL-Fehler ab, bevor überhaupt ein Resolver ausgeführt wird. Damit entfällt manuelles Prüfen des Auth-Status in jedem einzelnen Resolver.

Für feingranulare Autorisierung, etwa ob ein Nutzer eine bestimmte Bewertung bearbeiten darf, greift die Direktive @can auf bestehende Laravel-Policy-Klassen zu, exakt dieselben, die auch für Controller-Aktionen genutzt werden. Dieser Wiederverwendungseffekt ist einer der größten praktischen Vorteile von Lighthouse: Auth-Logik muss nicht doppelt für REST und GraphQL implementiert werden, sie lebt an einer zentralen Stelle im Laravel-Projekt.


<?php
declare(strict_types=1);

namespace App\Policies;

use App\Models\Review;
use App\Models\User;

// Reused for both REST controllers and GraphQL @can directives
final class ReviewPolicy
{
    public function update(User $user, Review $review): bool
    {
        return $user->id === $review->user_id || $user->hasRole('moderator');
    }
}

7. N+1-Probleme mit Batchloading lösen

Ohne Vorkehrungen führen verschachtelte GraphQL-Abfragen über Eloquent-Beziehungen zum klassischen N+1-Problem: Eine Query nach 50 Produkten mit jeweils zugehöriger Kategorie erzeugt naiv 51 Datenbankabfragen. Lighthouse löst das über eingebautes Batchloading, das automatisch aktiv wird, sobald Beziehungs-Direktiven wie @belongsTo oder @hasMany genutzt werden. Statt jede Beziehung einzeln aufzulösen, sammelt Lighthouse alle angefragten IDs innerhalb einer Query und lädt sie in einer einzigen, per whereIn gebündelten Abfrage nach.

Für eigene, nicht-standardmäßige Resolver, die nicht über die eingebauten Beziehungs-Direktiven laufen, muss Batchloading manuell mit dem BatchLoader-Interface implementiert werden, das Lighthouse für genau diesen Zweck bereitstellt. Wer eigene, komplexe Resolver schreibt und dabei vergisst, Batchloading zu berücksichtigen, handelt sich schnell Performance-Probleme ein, die erst bei größeren Datenmengen sichtbar werden, ein häufiger Fallstrick beim Übergang von einfachen Direktiven zu eigenem Resolver-Code.

8. Subscriptions in Lighthouse

Lighthouse unterstützt GraphQL-Subscriptions für Echtzeit-Updates, üblicherweise über Pusher oder Laravel Echo als Transport-Layer, kombiniert mit Redis für die Verteilung der Events über mehrere Server-Instanzen. Eine Subscription wird ähnlich wie eine Query im SDL definiert, mit der zusätzlichen @subscription-Direktive, die auf eine PHP-Klasse verweist, die entscheidet, welche verbundenen Clients ein bestimmtes Event erhalten sollen.

In der Praxis eignen sich Subscriptions in Lighthouse gut für Benachrichtigungen und Status-Updates, etwa den Bearbeitungsstatus einer Bestellung, sind aber kein Ersatz für hochfrequente Echtzeit-Anwendungsfälle wie Live-Chat mit sehr vielen gleichzeitigen Verbindungen, wofür spezialisierte WebSocket-Infrastruktur oft die bessere Wahl ist. Der Broadcasting-Layer von Laravel, den viele Projekte bereits für andere Zwecke konfiguriert haben, lässt sich direkt für Lighthouse-Subscriptions wiederverwenden.

9. Lighthouse vs. andere Laravel-GraphQL-Lösungen

Neben Lighthouse existieren weitere Wege, GraphQL in Laravel einzubinden, jede mit anderem Abstraktionsgrad und Kontrollumfang.

Ansatz Eloquent-Integration Kontrolle Einstiegsaufwand
Lighthouse (Nuwave) Direkt per SDL-Direktiven Mittel, punktuell eigene Resolver Niedrig
graphql-php direkt Manuell im Resolver-Code Vollständig Hoch
API Platform (Symfony) Nur mit Symfony/Doctrine sinnvoll Hoch, aber Symfony-gebunden Mittel
Laravel + reines REST Native Laravel-Konventionen Vollständig Niedrig

Für Laravel-Teams, die bereits stark auf Eloquent setzen und schnell eine funktionierende GraphQL-API brauchen, ist Lighthouse in aller Regel die richtige Wahl. Nur wenn ein Projekt sehr spezifische, von Standard-CRUD abweichende Ausführungsstrategien braucht, etwa eigenes Query-Batching auf Protokollebene, lohnt sich der Griff zu graphql-php direkt, mit entsprechend höherem Implementierungsaufwand.

Mironsoft

Laravel- und GraphQL-Architektur für datenintensive Anwendungen

GraphQL-API für euer Laravel-Projekt aufbauen?

Wir richten Lighthouse ein, modellieren euer Schema entlang eurer Eloquent-Struktur und sorgen mit Batchloading, sauberer Validierung und Guard-Direktiven für eine performante, sichere GraphQL-API.

Schema-Design

SDL-Direktiven passend zu bestehenden Eloquent-Modellen und Beziehungen modellieren

Performance

Batchloading gegen N+1-Probleme in eigenen Resolvern implementieren

Auth-Integration

Guards und Policies für REST und GraphQL zentral wiederverwenden

10. Zusammenfassung

Lighthouse reduziert den Aufwand für eine produktionsreife GraphQL-API in Laravel drastisch, indem es SDL-Direktiven direkt an Eloquent-Modelle, Validierungsregeln und Auth-Guards bindet. Für typische CRUD-lastige Domänen entfällt fast der komplette Resolver-Boilerplate, den eine manuelle graphql-php-Integration erfordern würde. Batchloading gegen N+1-Probleme ist für Standard-Beziehungen bereits eingebaut, für eigene Resolver muss es explizit implementiert werden.

Wer bereits in Laravel entwickelt, profitiert am meisten davon, dass Validierungsregeln, Policies und Guards zwischen REST und GraphQL geteilt werden können, statt Auth- und Validierungslogik doppelt zu pflegen. Für Projekte mit sehr spezifischen Ausführungsanforderungen bleibt der direkte Griff zu graphql-php eine Option, für die überwiegende Mehrheit der Laravel-Anwendungsfälle ist Lighthouse jedoch der pragmatischere und schnellere Weg.

Lighthouse GraphQL für Laravel — Das Wichtigste auf einen Blick

SDL-Direktiven

@all, @find, @paginate, @hasMany binden Felder direkt an Eloquent, ohne eigenen Resolver-Code.

Validierung & Auth

@rules, @guard und @can nutzen bestehende Laravel-Validierungsregeln, Guards und Policies wieder.

Batchloading

Für Standard-Beziehungsdirektiven automatisch aktiv, für eigene Resolver manuell über das BatchLoader-Interface.

Subscriptions

Echtzeit-Updates über Pusher/Laravel Echo und Redis, geeignet für Benachrichtigungen und Status-Änderungen.

11. FAQ: Lighthouse GraphQL für Laravel

1Was ist Lighthouse für Laravel?
Das führende GraphQL-Paket für Laravel, baut auf graphql-php auf und bindet Schemas per SDL-Direktiven direkt an Eloquent, Validierung und Auth-Guards.
2Braucht jedes Feld einen Resolver?
Nein, Direktiven wie @all, @find und @paginate erledigen Standardfälle automatisch. Eigene Resolver nur für komplexe Fachlogik.
3Wie funktioniert Mutation-Validierung?
Über @rules mit denselben Regeln wie Laravel Form Requests. Fehler landen strukturiert im errors-Array mit validation-Objekt.
4Wie schützt man Felder gegen Unauth?
Mit @guard für Auth-Guards und @can für feingranulare Policies, beide aus dem bestehenden Laravel-Setup wiederverwendet.
5Löst Lighthouse N+1 automatisch?
Für Standard-Beziehungsdirektiven ja, per eingebautem Batchloading. Eigene Resolver brauchen manuelles BatchLoader-Interface.
6Läuft Lighthouse parallel zu REST?
Ja, problemlos. Beide teilen sich Datenbank, Eloquent-Modelle, Validierung und Policies.
7Unterstützt Lighthouse Subscriptions?
Ja, über @subscription mit Pusher oder Laravel Echo als Transport und Redis zur Verteilung über Server-Instanzen.
8Wann direkt graphql-php statt Lighthouse?
Bei sehr spezifischen Ausführungsstrategien jenseits von Standard-CRUD, etwa eigenem Protokoll-Batching.
9Wie testet man ein Lighthouse-Schema?
Mit PHPUnit über das mitgelieferte GraphQL-Test-Trait, ähnlich Laravel-Feature-Tests für REST.
10Für kleine Projekte geeignet?
Ja, niedriger Einstiegsaufwand ist gerade dort ein Vorteil. Für sehr einfache APIs kann reines REST trotzdem pragmatischer sein.