Melhores práticas em GraphQL
GraphQL é suficientemente maduro, e está presente há tempo suficiente, para que a comunidade tenha publicado numerosos artigos compartilhando melhores práticas. Essas guias cobrem praticamente todos os aspectos do GraphQL, incluindo design de schema, convenções de nomenclatura, tratamento de segurança e fornecimento de erros significativos, entre outros.
Estas são algumas das guias mais relevantes sobre melhores práticas em GraphQL.
Melhores práticas em graphql.org
O site oficial do GraphQL oferece uma introdução geral às melhores práticas em GraphQL.
Esses itens cobrem principalmente preocupações de alto nível, como:
- Qual é a melhor maneira de paginar os resultados
- Onde o layer GraphQL se posiciona dentro da arquitetura
- Como usar a interface Node para identificação global de objetos
- Como armazenar resultados em cache
- E muitos outros

As recomendações de Lee Byron
Pouco depois de lançar o GraphQL ao mundo, o criador do GraphQL Lee Byron publicou o artigo Lessons From 4 Years of GraphQL, descrevendo como devemos conceitualmente tentar trabalhar com GraphQL:
- Nomenclatura importa
- Pense em grafos, não em endpoints
- Descreva os dados, não a visão
- GraphQL é uma interface leve
- Oculte detalhes de implementação
Ele também detalha vários princípios e lições valiosas que aprendeu ao usar GraphQL no Facebook.
GraphQL Rules
GraphQL Rules é um site especialmente dedicado a apresentar as melhores práticas do dia a dia para trabalhar com GraphQL, abordando principalmente o design do schema GraphQL.
Este recurso é muito completo. Ele compila informações de alguns recursos excepcionais (como o artigo Designing GraphQL Mutations e o tutorial da Shopify Designing a GraphQL API) e os apresenta todos juntos de forma concisa.
As regras descritas incluem:
- Regras de nomenclatura
- Use
camelCasepara campos e argumentos GraphQL. - Use
UpperCamelCasepara tipos GraphQL. - Use
CAPITALIZED_WITH_UNDERSCORESpara nomear tipos ENUM.
- Use
- Regras de tipos
- Use tipos escalares personalizados se quiser declarar campos ou argumentos com valor semântico específico.
- Use Enum para campos que contêm um conjunto específico de valores.
- Regras de campos (Output)
- Use nomes semânticos para os campos e evite vazar detalhes de implementação nos nomes dos campos.
- Use o campo
Non-Nullse o campo sempre terá um determinado valor. - Agrupe o maior número possível de campos relacionados em um Object type personalizado.
- Regras de argumentos (Input)
- Agrupe argumentos relacionados em um novo input-type.
- Use tipos escalares rigorosos para argumentos, por exemplo
DateTimeem vez deString. - Marque argumentos como
requiredse forem necessários para a execução da query.
- Regras de listas
- Para filtrar listas, use o argumento
filter, que contém todos os filtros disponíveis. - Use o argumento
sortdo tipoEnumou[Enum!]para ordenação de listas. - Use
limitcom valor padrão eskippara limitar o número de itens retornados na lista. - Use os argumentos
page,perPagepara paginação e retorne um output type comitems(array de elementos) epageInfo(metadados). - Para listas infinitas (scroll infinito), use a Relay Cursor Connections Specification.
- Para filtrar listas, use o argumento
- Regras de mutations
- Use Namespace-types para agrupar mutations dentro de um único recurso.
- Vá além do CRUD — crie mutations pequenas para diferentes operações de negócio nos recursos.
- Considere a possibilidade de executar mutations em múltiplos itens (alterações batch do mesmo tipo).
- As mutations devem descrever claramente todos os argumentos obrigatórios; não deve haver opções either-either.
- Nas mutations, coloque todas as variáveis em um único argumento input.
- Cada mutation deve ter um payload type único.
Melhores práticas para resolvers
O artigo GraphQL Resolvers: Best Practices descreve como criar melhor os resolvers de campos. Embora seja voltado para servidores Node.js (a infraestrutura do PayPal é baseada em Express), várias de suas lições também podem ser aplicadas a outras tecnologias, incluindo PHP.
Os principais aprendizados são:
- Buscar e passar dados de pai para filho deve ser usado com moderação.
- Use bibliotecas como dataloader para deduplicar requisições downstream.
- Esteja ciente de qualquer pressão que você está causando nas suas fontes de dados.
- Não mute "context". Garante um código consistente e com menos bugs.
- Escreva resolvers legíveis, manuteníveis e testáveis. Não muito complexos.
- Torne seus resolvers o mais enxutos possível. Extraia a lógica de busca de dados para funções async reutilizáveis.
OWASP - GraphQL Cheat Sheet
OWASP (Open Web Application Security Project) é uma fundação sem fins lucrativos que trabalha para melhorar a segurança de software. Realiza pesquisas sobre como diferentes tecnologias são vulneráveis a exploits e descreve detalhadamente soluções para problemas de segurança, facilitando para os desenvolvedores a prevenção de ataques.
OWASP publicou a GraphQL Cheat Sheet, explicando quais são os ataques mais comuns e os maiores problemas de segurança em GraphQL, e como abordá-los.
Os ataques comuns ao GraphQL são:
- Injection - isso geralmente inclui, mas não se limita a:
- Injection SQL e NoSQL
- Injection de comandos OS
- Injection SSRF e CRLF / Request Smuggling
- DoS (Denial of Service)
- Abuso de autorização quebrada: acesso impróprio ou excessivo, incluindo IDOR
- Batching Attacks, um método de ataque brute force específico do GraphQL
- Abuso de configurações padrão inseguras
O OWASP então fornece recomendações sobre como evitar cada um desses casos.
Melhores práticas com queries GraphQL
A equipe do Apollo publicou as GraphQL query best practices, oferecendo insights práticos sobre maneiras concretas de compor a query GraphQL.
Por exemplo, essas duas queries atingem o mesmo objetivo, mas como a primeira tem um nome de operação, ela é mais compreensível e útil durante o debugging:
# Recomendado ✅
query GetBooks {
books {
title
}
}
# Não recomendado ❌
query {
books {
title
}
}As sugestões deles incluem:
- Nomear todas as operações
- Usar variáveis para fornecer argumentos GraphQL
- Consultar apenas os dados de que você precisa, onde precisa
- Usar fragments para encapsular conjuntos de campos relacionados
- Consultar dados globais e dados específicos do usuário separadamente
Aproveitando o one graph
Também da equipe do Apollo, o site Principled GraphQL explica que GraphQL não é apenas uma especificação, mas, possivelmente mais importante, uma interface para interagir com o "grafo" de dados da nossa empresa.
Por meio de uma lista de 10 princípios, este site descreve como aproveitar ao máximo o grafo único:
- One Graph: sua empresa deve ter um grafo unificado, em vez de múltiplos grafos criados por cada equipe.
- Federated Implementation: embora haja apenas um grafo, a implementação desse grafo deve ser federada entre múltiplas equipes.
- Track the Schema in a Registry: deve haver uma única fonte da verdade para registrar e rastrear o grafo.
- Abstract, Demand-Oriented Schema: o schema deve atuar como uma camada de abstração que oferece flexibilidade aos consumidores enquanto oculta os detalhes de implementação do serviço.
- Use an Agile Approach to Schema Development: o schema deve ser construído incrementalmente com base em requisitos reais e evoluir suavemente ao longo do tempo.
- Iteratively Improve Performance: o gerenciamento de desempenho deve ser um processo contínuo, baseado em dados, adaptando-se progressivamente às cargas de queries e implementações de serviços em evolução.
- Use Graph Metadata to Empower Developers: os desenvolvedores devem ser equipados com rica consciência do grafo durante todo o processo de desenvolvimento.
- Access and Demand Control: conceda acesso ao grafo por cliente e gerencie o que e como os clientes podem acessá-lo.
- Structured Logging: capture logs estruturados de todas as operações do grafo e utilize-os como a principal ferramenta para entender o uso do grafo.
- Separate the GraphQL Layer from the Service Layer: adote uma arquitetura em camadas com a funcionalidade do grafo dividida em uma camada separada em vez de incorporada em cada serviço.