GraphQL vs REST in PHP: Architekturkrieg oder Werkzeuge für verschiedene Aufgaben?
\n\nWenn Sie wieder einmal Ihren Code-Editor öffnen, um einen neuen Endpunkt für Ihre PHP-Anwendung zu schreiben, verlässt Sie ein Gefühl des Déjà-vu nicht. Schon wieder einen Controller erstellen? Schon wieder eine Validierung schreiben? Oder ist es vielleicht an der Zeit, etwas Neues auszuprobieren? Die Debatte zwischen GraphQL und REST in der Welt der PHP-Entwicklung erinnert an die ewige Debatte zwischen „Lara“ und „Symfony“ – jeder verteidigt seinen Stack bis zur Heiserkeit. Aber seien wir ehrlich: Beide Ansätze sind keine Religion, sondern Werkzeuge. Und heute werden wir sie bis ins kleinste Detail zerlegen, uns echten Code ansehen und entscheiden, wann REST API auf PHP Ihre Wahl ist und wann Sie sich GraphQL in PHP genauer ansehen sollten.
\n\nKurze Einführung: Was ist was?
\n\nREST (Representational State Transfer) ist ein Architekturstil, der auf den Prinzipien von Ressourcen und HTTP-Methoden basiert. Sie greifen auf /api/users zu und erhalten eine Liste von Benutzern. Möchten Sie einen einzelnen Benutzer, fügen Sie /api/users/42 hinzu. Alles logisch, vorhersehbar und banal.
GraphQL ist eine von Facebook entwickelte Abfragesprache. Sie sind nicht an URLs gebunden. Sie senden eine einzige Anfrage an einen einzigen Endpunkt (z. B. /graphql) und sagen: „Gib mir den Namen von Benutzer 42, seine letzten 5 Beiträge und die Anzahl der Likes unter jedem.“ Der Server gibt genau das zurück, was Sie angefordert haben. Kein Byte mehr.
Scheinbar ist GraphQL der Punktsieger. Aber werfen Sie den guten alten REST noch nicht weg. Jeder hat seine Tücken, insbesondere im Kontext der Entwicklung mit PHP.
\n\nVergleich der Architekturen: Von der Theorie zum Code
\n\nREST: Der Klassiker
\n\nIn PHP wird REST über Routing implementiert. Frameworks wie Laravel oder Symfony machen das elegant. Beispiel eines typischen REST-Controllers in Laravel:
\n\n<?php\n\nnamespace App\\Http\\Controllers\\Api;\n\nuse App\\Models\\User;\nuse Illuminate\\Http\\Request;\n\nclass UserController extends Controller\n{\n public function index()\n {\n return User::all();\n }\n\n public function show($id)\n {\n $user = User::with('posts.comments')->findOrFail($id);\n return response()->json($user);\n }\n\n public function store(Request $request)\n {\n $validated = $request->validate([\n 'name' => 'required|string',\n 'email' => 'required|email|unique:users',\n ]);\n\n $user = User::create($validated);\n return response()->json($user, 201);\n }\n}\n\nDie Vorteile liegen auf der Hand: einfaches Caching (HTTP-Cache, Varnish), klare URL-Struktur, breite Unterstützung durch Tools (Postman, Swagger). Nachteile – das Problem des Over-fetching und Under-fetching. Wenn das Frontend nur die Benutzernamen benötigt, Sie aber in der Antwort alle Felder des Modells mitschleppen, ist das Over-fetching. Wenn Sie den Namen und die Freundesliste benötigen, aber zwei Anfragen stellen müssen, ist das Under-fetching.
\n\nGraphQL: Flexibilität mit einem Haken
\n\nFür die Implementierung von GraphQL in PHP gibt es hervorragende Bibliotheken: webonyx/graphql-php (reines PHP) und lighthouse-php/lighthouse (für Laravel). Beispiel eines Schemas und Resolvers mit graphql-php:
\n\n<?php\n\nuse GraphQL\\GraphQL;\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\nuse GraphQL\\Type\\Schema;\n\n$userType = new ObjectType([\n 'name' => 'User',\n 'fields' => [\n 'id' => Type::int(),\n 'name' => Type::string(),\n 'email' => Type::string(),\n 'posts' => [\n 'type' => Type::listOf($postType),\n 'resolve' => function ($user) {\n return getPostsByUserId($user['id']);\n }\n ],\n ],\n]);\n\n$queryType = new ObjectType([\n 'name' => 'Query',\n 'fields' => [\n 'user' => [\n 'type' => $userType,\n 'args' => [\n