GraphQL vs REST em PHP: guerra de arquiteturas ou ferramentas para diferentes tarefas?
\n\nQuando você abre o editor de código mais uma vez para criar um novo endpoint para sua aplicação PHP, aquela sensação de déjà vu não te abandona. Criar outro controller? Escrever validação de novo? Ou será que está na hora de experimentar algo novo? O debate entre GraphQL e REST no mundo do desenvolvimento PHP lembra a discussão eterna entre Laravel e Symfony — cada um defende seu stack até ficar rouco. Mas vamos ser honestos: ambas as abordagens não são religião, são ferramentas. E hoje vamos desmontá-las peça por peça, ver código real e decidir quando o REST API em PHP é sua melhor escolha, e quando vale a pena considerar o GraphQL em PHP.
\n\nPequena introdução: o que é cada um?
\n\nREST (Representational State Transfer) é um estilo arquitetural baseado em recursos e métodos HTTP. Você acessa /api/users e recebe uma lista de usuários. Quer um específico? Adicione /api/users/42. Tudo lógico, previsível e direto.
GraphQL é uma linguagem de consulta criada pelo Facebook. Você não fica preso a URLs. Envia uma única requisição para um endpoint único (por exemplo, /graphql) e diz: "Me dê o nome do usuário 42, seus últimos 5 posts e a quantidade de curtidas em cada um". O servidor retorna exatamente o que você pediu. Nem um byte a mais.
Parece que GraphQL vence de lavada, certo? Mas não se apresse em descartar o bom e velho REST. Cada um tem suas armadilhas, especialmente no contexto do desenvolvimento em PHP.
\n\nComparação de arquiteturas: da teoria ao código
\n\nREST: o clássico
\n\nEm PHP, REST é implementado através de roteamento. Frameworks como Laravel ou Symfony fazem isso com elegância. Exemplo de um controller REST típico no 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\nAs vantagens são óbvias: simplicidade de cache (HTTP cache, Varnish), estrutura de URL clara e amplo suporte de ferramentas (Postman, Swagger). As desvantagens — problemas de over-fetching e under-fetching. Se o frontend precisa apenas dos nomes dos usuários e você retorna todos os campos do modelo, isso é over-fetching. Se precisa do nome e da lista de amigos, e você faz duas requisições, isso é under-fetching.
\n\nGraphQL: flexibilidade com pegadinhas
\n\nPara implementar GraphQL em PHP, existem bibliotecas excelentes: webonyx/graphql-php (PHP puro) e lighthouse-php/lighthouse (para Laravel). Exemplo de schema e resolver com 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