GraphQL Java — biblioteca servidora para implementação de API GraphQL em Java
GraphQL Java é uma biblioteca servidora poderosa e flexível para implementar a especificação GraphQL na linguagem Java. Ela permite que desenvolvedores criem APIs eficientes, type-safe e facilmente extensíveis, dando aos clientes a capacidade de solicitar apenas os dados necessários. A biblioteca é ativamente mantida pela comunidade e usada em ambiente de produção por muitas grandes empresas.
Principais recursos
- Suporte completo à especificação GraphQL — implementação de todos os tipos, diretivas, mutações, subscriptions e fragmentos.
- Sistema de tipos flexível — possibilidade de definir schemas tanto com base em classes Java (code-first) quanto via SDL (schema-first).
- Suporte nativo a assincronia — uso de
CompletableFuturepara processamento eficiente de requisições. - DataLoader — utilitário integrado para resolver o problema de consultas N+1 e carregamento em lote de dados.
- Ferramentas de teste — classes integradas para teste unitário de schemas e resolvers.
- Extensibilidade — suporte a scalars personalizados, diretivas e ferramentas de validação.
Arquitetura da biblioteca
A biblioteca consiste em vários componentes-chave:
- GraphQLSchema — objeto que representa o schema da API.
- DataFetcher — interface funcional para obter dados (análogo ao resolver no GraphQL).
- TypeResolver — interface para resolver tipos polimórficos (interfaces e union).
- ExecutionStrategy — estratégia de execução de consulta (assíncrona por padrão).
- Instrumentation — mecanismo para adicionar lógica adicional (logging, métricas).
Exemplo de uso
Vamos considerar um exemplo simples de criação de um servidor GraphQL para gerenciar livros.
1. Definição do schema via SDL
// schema.graphqlstype Query { books: [Book] bookById(id: ID!): Book}
type Book { id: ID! title: String! author: String! year: Int}2. Criação dos resolvers
import graphql.schema.DataFetcher;import graphql.schema.DataFetchingEnvironment;
public class BookDataFetcher {
public static DataFetcher<List<Book>> getBooksDataFetcher() { return environment -> { // Em uma aplicação real, aqui haveria uma consulta ao banco de dados return List.of( new Book("1", "1984", "George Orwell", 1949), new Book("2", "Brave New World", "Aldous Huxley", 1932) ); }; }
public static DataFetcher<Book> getBookByIdDataFetcher() { return environment -> { String id = environment.getArgument("id"); // Buscar livro por ID return findBookById(id); }; }}3. Montagem do schema e execução da consulta
import graphql.GraphQL;import graphql.schema.GraphQLSchema;import graphql.schema.idl.RuntimeWiring;import graphql.schema.idl.SchemaParser;import graphql.schema.idl.SchemaGenerator;import graphql.schema.idl.TypeDefinitionRegistry;
public class GraphQLExample { public static void main(String[] args) { // Carregar SDL String schema = "type Query { books: [Book] } type Book { id: ID! title: String! }"; SchemaParser schemaParser = new SchemaParser(); TypeDefinitionRegistry typeRegistry = schemaParser.parse(schema);
// Configurar runtime wiring RuntimeWiring wiring = RuntimeWiring.newRuntimeWiring() .type("Query", builder -> builder .dataFetcher("books", BookDataFetcher.getBooksDataFetche