Drupal como backend: GraphQL, JSON:API, RESTful e o erro caro escondido na escolha da API
Certa vez, um CTO me perguntou no meio de uma reunião de planejamento de Drupal decoupled: «Então, qual API devemos usar?»
Por um segundo, a sala ficou em silêncio. O frontend queria GraphQL. O backend queria JSON:API. Um empreiteiro de integração já havia sugerido REST. O product owner só queria que o aplicativo móvel parasse de esperar pelos releases do site.
Essa pequena pergunta costuma soar técnica. Mas não é. É uma questão de governança, uma questão de orçamento e, às vezes, uma questão de contratação, disfarçada com o moletom de um desenvolvedor.
O Drupal pode ser um backend muito poderoso para produtos decoupled. Ele já tem conteúdo estruturado, papéis, permissões, workflows, revisões, traduções, gestão de mídia, taxonomia e um ecossistema maduro de módulos. A parte desconfortável é decidir exatamente como esse conteúdo vai sair do Drupal. O núcleo do Drupal tem suporte nativo a JSON:API, o GraphQL está disponível por meio de um módulo contribuído, e o módulo RESTful Web Services do Drupal continua sendo uma opção para endpoints personalizados no estilo de recursos. A própria documentação do Drupal sobre a abordagem decoupled formula a divisão de forma direta: o JSON:API está no núcleo, o GraphQL é um módulo contribuído, e o Drupal pode entregar conteúdo a um frontend externo por meio de uma API.
E, ainda assim, as equipes continuam escolhendo mal.
Escolhem GraphQL porque soa moderno. Escolhem REST porque todo mundo já usou. Escolhem JSON:API porque já está lá. Nada disso é uma estratégia.
Aqui vai uma versão mais dura: para a maioria das plataformas de conteúdo baseadas em Drupal, o JSON:API deveria ser o ponto de partida padrão. O GraphQL precisa ser conquistado. O REST deveria ser reservado para os casos em que as outras duas opções são amplas demais ou impositivas demais em suas suposições.
Isso vai irritar algumas pessoas. Ótimo.
Comece pelo vencedor entediante
REST virou uma daquelas palavras que significam qualquer coisa que quem fala precise que signifiquem. Às vezes significa HTTP puro orientado a recursos. Às vezes significa «devolvemos JSON de um controller». Às vezes significa «o fornecedor nos deu um endpoint e um PDF».
A dissertação de Roy Fielding apresentou o REST como um estilo arquitetural para sistemas de hipermídia distribuídos, com restrições como separação client-server, comunicação stateless, cache, uniform interface, layered systems e code-on-demand opcional. Essa ideia original é mais rigorosa do que boa parte do que se chama de REST nos planos de projeto.
O módulo RESTful Web Services do Drupal é útil porque pode expor recursos com métodos específicos, formatos de serialização e autenticação. Os materiais de aprendizado do Drupal descrevem recursos REST para entidades, suporte a métodos como GET, POST, PATCH e DELETE, serialização em JSON ou XML e autenticação via Basic Auth, cookies ou outros módulos, como OAuth. Também se observa que os métodos inseguros exigem o request header X-CSRF-Token.
Isso torna o REST uma boa opção para tarefas de integração restritas.
Um provedor de pagamento envia ao Drupal o status de uma transação. Um sistema de estoque busca a lista de manuais de produto atualizados. Um partner portal precisa de um único endpoint cuidadosamente moldado para assets aprovados. Um aplicativo móvel legado já espera por /api/v1/articles/{id} e não pode ser reescrito neste trimestre.
O REST lhe dá controle. Ele também lhe dá a síndrome da folha em branco.
Ao contrário do JSON:API, em que as convenções já foram escolhidas, um endpoint REST personalizado exige decisões: forma da URL, formato da resposta, formato de erro, estilo de paginação, sintaxe de filtragem, versionamento, autenticação, cache headers, documentação, política de deprecation. O OpenAPI pode ajudar a documentar essa superfície, e a OpenAPI Specification é uma forma padrão e independente de linguagem de descrever APIs HTTP para que pessoas e computadores possam entendê-las sem ler o código-fonte.
Mas você ainda terá de fazer as escolhas.
E essa escolha permanece. Um endpoint descuidado, projetado na segunda semana, pode assombrar o produto por anos, porque alguma versão do aplicativo em produção ainda depende dele.
A decisão não é «qual API é a melhor?»
Essa forma de colocar a questão é preguiçosa. Desculpe, mas é.
A pergunta melhor é: que tipo de acoplamento a sua organização pode se dar ao luxo de ter?
O JSON:API acopla os consumidores ao modelo de entidades do Drupal. Isso costuma ser aceitável quando o Drupal é o sistema de conteúdo principal e o frontend é uma camada de apresentação substituível. A recompensa é velocidade e menos reinvenção no backend.
O GraphQL acopla os consumidores a um schema projetado pela sua equipe. Se bem feito, esse schema esconde o Drupal e expressa o domínio do produto. Se mal feito, ele se torna um segundo modelo de CMS mantido em código.
O REST acopla os consumidores a endpoints personalizados. Isso é ótimo para integrações específicas e perigoso para a distribuição ampla de conteúdo, porque cada endpoint se torna um produto em miniatura com sua própria cauda de manutenção.
Aqui está a versão que eu levaria a uma steering group executiva.
| Situação | Minha recomendação | Por quê |
|---|---|---|
| Site headless ou aplicativo que lê conteúdo do Drupal | Comece com JSON:API | Está no núcleo do Drupal, expõe entidades rapidamente e usa as permissões e o cache do Drupal. |
| Vários frontends precisam de formas diferentes do mesmo conteúdo | Considere GraphQL | Os clientes podem solicitar campos selecionados por meio de um schema tipado, mas o GraphQL no Drupal exige projeto e mapeamento do schema. |
| Integração de parceiro ou conexão pontual de sistema | Use REST | Recursos REST personalizados podem ser moldados para a integração e controlados por método, formato e autenticação. |
| O modelo do Drupal está bagunçado, mas não pode ser organizado tão cedo | GraphQL ou REST personalizado podem proteger os consumidores | Uma API projetada pode esconder campos internos, embora acrescente custo de ownership e de manutenção. |
| Equipe pequena, prazo apertado, majoritariamente entrega de conteúdo | JSON:API | Menos código de API personalizado geralmente significa menos surpresas. O JSON:API do Drupal não requer configuração e entende entidades. |
Tabelas são um pouco estéreis, mas esta economiza reuniões.
No que os project managers devem prestar atenção
A escolha da API muda o plano do projeto mais do que as pessoas admitem.
Com o JSON:API, o caminho crítico é a modelagem de conteúdo. Se o modelo de conteúdo for bem pensado, o trabalho de API pode andar rápido. Se o modelo de conteúdo for caótico, o desenvolvimento do frontend desacelera, porque cada requisição revela mais um compromisso editorial. Direcione a atenção dos especialistas seniores para a nomenclatura dos campos, os paragraph patterns reutilizáveis, as relações de mídia, a taxonomia e as permissões antes que a equipe de frontend comece a montar as páginas.
Com o GraphQL, o caminho crítico é o ownership do schema. Quem projeta o schema? Quem revisa as breaking changes? Quem escreve os resolvers? Quem cuida de problemas de desempenho, como consultas aninhadas que disparam carregamentos demais no backend? O módulo GraphQL do Drupal fornece ferramentas e extension points, incluindo data producer plugins e o GraphiQL, mas não elimina a necessidade de disciplina de engenharia de backend.
Com o REST, o caminho crítico é a disciplina de contrato. Cada endpoint precisa de documentação, testes, regras de autenticação, semântica de erros e um histórico de versionamento. O REST parece barato quando o primeiro endpoint é construído. O quinto endpoint conta a verdade.
Mais uma coisa. A autenticação costuma ser subestimada. O JSON:API do Drupal está ligado aos sistemas de autenticação e autorização do Drupal, e o REST pode usar authentication providers como Basic Auth e cookies, sendo o OAuth frequentemente adicionado por meio de módulos contribuídos. A documentação do Lupus Decoupled Drupal aponta o Simple OAuth como forma de autenticar requisições de API por token em configurações decoupled.
Não deixe isso para o sprint antes do lançamento. Esse sprint já está amaldiçoado.
Desempenho: o argumento que todos simplificam
Os fãs de GraphQL dizem que ele evita over-fetching. Verdade. Os fãs de JSON:API dizem que os includes reduzem o número de round trips. Também verdade. Os fãs de REST dizem que o cache HTTP é simples. Verdade de novo.
Agora a parte desagradável: as três opções podem ser rápidas, e as três podem ser lentas.
O GraphQL pode reduzir o tamanho do payload, mas consultas aninhadas complexas podem punir o backend se os resolvers forem escritos de forma descuidada. O JSON:API pode usar o response caching do Drupal e os includes, mas os payloads podem ser verbosos. O REST pode se encaixar bem no cache HTTP, mas endpoints personalizados costumam esquecer a cacheability até o início dos testes de desempenho. As restrições de REST de Fielding incluem cache, porque o cache pode reduzir o tráfego de rede e a latência, mas dados obsoletos e cache invalidation continuam sendo trade-offs reais. A documentação do JSON:API do Drupal liga explicitamente o módulo ao response caching do Drupal, e o módulo GraphQL no Drupal.org está classificado nas categorias Decoupled, Developer tools e Performance.
Então não, o GraphQL não é automaticamente «a opção de desempenho».
O primeiro ganho de desempenho geralmente vem de um modelo de conteúdo melhor. O segundo, de uma estratégia de cache. O terceiro, de evitar comportamentos bobos do cliente, como chamar o mesmo endpoint doze vezes porque ninguém escreveu uma data access layer.
Glamouroso? Não. Eficaz? Sim.
Um framework de escolha direto
Se eu estivesse assessorando um founder ou um CTO, começaria com esta sequência.
Primeiro, use as páginas renderizadas comuns do Drupal, a menos que você tenha um motivo para decouple. O decoupling adiciona complexidade em hosting, preview, routing, cache, deployment, autenticação e debugging. A própria documentação decoupled do Drupal separa o Drupal padrão do Drupal decoupled, observando que o layout migra para o frontend e o backend expõe o conteúdo por meio de uma API. Essa mudança não é gratuita.
Segundo, se você faz decouple principalmente por causa de um frontend moderno, comece com o JSON:API. Construa uma página real, não uma demo. Inclua mídia, menus ou navegação, conteúdo relacionado, necessidades de preview, autenticação quando necessário e comportamento de cache. Você aprenderá mais com uma página feia do que com seis diagramas de arquitetura.
Terceiro, migre para o GraphQL somente quando a experiência do consumidor justificar o trabalho com o schema. Bons motivos incluem vários consumidores de frontend, a necessidade de esconder as entranhas do Drupal, content graphs complexos ou agregação entre sistemas. Maus motivos incluem «nosso desenvolvedor de frontend gosta do Apollo» e «o investor deck diz GraphQL».
Quarto, use o REST para integrações que precisam de limites rígidos. Um endpoint personalizado para exportação de parceiro pode ser limpo. Uma plataforma de conteúdo inteira feita de endpoints improvisados pode virar uma caixa de chaves sem etiqueta.
E organize o modelo do Drupal. Por favor. Nenhuma camada de API consegue salvar por completo um modelo de conteúdo que ninguém dona.
A política do «future-proof»
Os executivos gostam da expressão «future-proof». Eu entendo por quê. Ninguém quer aprovar uma reconstrução de backend e ouvir, dezoito meses depois, que a API escolhida encurralou a empresa.
Mas o future-proofing geralmente tem menos a ver com escolher a API mais na moda e mais a ver com onde as mudanças têm permissão de acontecer.
O JSON:API diz: «O modelo do Drupal é o contrato». Isso é honesto e rápido.
O GraphQL diz: «Nosso schema de produto é o contrato». Isso é poderoso e caro.
O REST diz: «Este endpoint é o contrato». Isso é preciso e se multiplica facilmente em um problema de manutenção.
Não há um vencedor universal. Há apenas adequação.
Minha abordagem é simples: comece com a coisa menos personalizada que consiga sustentar o produto. No Drupal, isso geralmente significa JSON:API. Acrescente GraphQL quando você puder nomear um dono e um orçamento. Acrescente REST quando a integração for específica o bastante para merecer a própria porta.
A pior escolha é aquela feita por moda, porque a moda nunca aparece para dar suporte.
Procurando a empresa nº 1 do mercado em desenvolvimento Drupal? Você acabou de encontrá-la.
Somos a melhor agência digital especializada em Drupal, criada para entregar rapidamente plataformas seguras e escaláveis sem concessões. De novos projetos e redesigns a migrações e suporte de longo prazo, nossos especialistas em Drupal entregam resultados de nível enterprise com o cuidado de uma agência boutique.
Agende uma ligação hoje e vamos transformar o seu roadmap de Drupal em uma realidade de alto desempenho.
Ivan Abramenko, Principal Drupal Architect
ivan.abramenko@drupalbook.org
projects@drupalbook.org