GraphQL Java — server library for implementing GraphQL API in Java
GraphQL Java is a powerful and flexible server library for implementing the GraphQL specification in Java. It allows developers to create efficient, type-safe, and easily extensible APIs, giving clients the ability to request only the necessary data. The library is actively supported by the community and is used in production environments by many large companies.
Key Features
- Full support for the GraphQL specification — implementation of all types, directives, mutations, subscriptions, and fragments.
- Flexible type system — ability to define schemas both based on Java classes (code-first) and via SDL (schema-first).
- Built-in asynchronous support — using
CompletableFuturefor efficient request processing. - DataLoader — built-in utility for solving the N+1 query problem and batch data loading.
- Testing tools — built-in classes for unit testing schemas and resolvers.
- Extensibility — support for custom scalars, directives, and validation tools.
Library Architecture
The library consists of several key components:
- GraphQLSchema — an object representing the API schema.
- DataFetcher — a functional interface for fetching data (analogous to a resolver in GraphQL).
- TypeResolver — an interface for resolving polymorphic types (interfaces and unions).
- ExecutionStrategy — the query execution strategy (asynchronous by default).
- Instrumentation — a mechanism for injecting additional logic (logging, metrics).
Usage Example
Let's look at a simple example of creating a GraphQL server for managing books.
1. Defining the schema via SDL
// schema.graphqlstype Query { books: [Book] bookById(id: ID!): Book}
type Book { id: ID! title: String! author: String! year: Int}2. Creating resolvers
import graphql.schema.DataFetcher;import graphql.schema.DataFetchingEnvironment;
public class BookDataFetcher {
public static DataFetcher<List<Book>> getBooksDataFetcher() { return environment -> { // In a real application, this would be a database query 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"); // Search for a book by ID return findBookById(id); }; }}3. Building the schema and executing a query
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) { // Loading SDL String schema = "type Query { books: [Book] } type Book { id: ID! title: String! }"; SchemaParser schemaParser = new SchemaParser(); TypeDefinitionRegistry typeRegistry = schemaParser.parse(schema);
// Configuring runtime wiring RuntimeWiring wiring = RuntimeWiring.newRuntimeWiring() .type("Query", builder -> builder .dataFetcher("books", BookDataFetcher.getBooksDataFetche