compile 'io.micronaut.graphql:micronaut-graphql:1.2.1'
Table of Contents
Micronaut GraphQL Integration
Extensions to integrate Micronaut and GraphQL
Version: 1.2.1
1 Introduction
Micronaut supports GraphQL via the micronaut-graphql
module.
Release History
1.2.1
-
Fixed
DefaultGraphQLInvocation
not handling exceptions thrown by GraphQL’sexecuteAsync
(#21). -
Added
defaultVariableEditorOpen: true
property to the GraphiQL template.
1.2.0
1.1.0
-
Upgrade to GraphQL Java
13.0
.
1.0.2
-
Fixed content type resolution (#7).
1.0.1
-
Fixed loading GraphiQL configuration (#6).
1.0.0
-
Removed the
GraphQLContextBuilder
andGraphQLRootBuilder
in favour of a more genericGraphQLExecutionInputCustomizer
capable of transforming theExecutionInput
before execution.
1.0.0.RC2
-
Upgrade to GraphQL Java
12.0
. -
Introduced a
GraphQLJsonSerializer
interface and defaultJacksonGraphQLJsonSerializer
implementation capable of providing a customized JacksonObjectMapper
, or plugging in a completely different JSON serializer/deserializer library.
1.0.0.RC1
-
Initial release.
2 Configuration
Micronaut 1.0.3 or above is required and you must have the micronaut-graphql
dependency on your classpath:
<dependency>
<groupId>io.micronaut.graphql</groupId>
<artifactId>micronaut-graphql</artifactId>
<version>1.2.1</version>
</dependency>
The micronaut-graphql
module transitively includes the com.graphql-java:graphql-java
dependency and provides a Micronaut
GraphQLController
which enables query execution via HTTP.
As outlined in https://graphql.org/learn/serving-over-http the following HTTP requests are supported:
-
GET
request withquery
,operationName
andvariables
query parameters. Thevariables
query parameter must be json encoded. -
POST
request withapplication/json
body and keysquery
(String),operationName
(String) andvariables
(Map).
Both produce a application/json
response.
By default the GraphQL endpoint is exposed on /graphql
but this can be changed via the graphql.path
application property.
graphql:
enabled: true (1)
path: /graphql (2)
1 | Enables/disables the GraphQL integration. Default true . |
2 | Configures the GraphQL endpoint path. Default /graphql . |
You only must configure a bean of type graphql.GraphQL
containing the GraphQL schema and runtime wiring.
2.1 Configuring the GraphQL Bean
The graphql.GraphQL
bean can be defined by solely using the GraphQL Java implementation,
or in combination with other integration libraries like GraphQL Java Tools
or GraphQL SPQR. As mentioned before the first one is added as transitive dependency, other
integration libraries must be added to the classpath manually.
Below is a typical example of a Micronaut Factory class
configuring a graphql.GraphQL
Bean using the
GraphQL Java library.
import graphql.GraphQL;
import graphql.schema.GraphQLSchema;
import graphql.schema.idl.RuntimeWiring;
import graphql.schema.idl.SchemaGenerator;
import graphql.schema.idl.SchemaParser;
import graphql.schema.idl.TypeDefinitionRegistry;
import io.micronaut.context.annotation.Bean;
import io.micronaut.context.annotation.Factory;
import io.micronaut.core.io.ResourceResolver;
import javax.inject.Singleton;
import java.io.BufferedReader;
import java.io.InputStreamReader;
@Factory (1)
public class GraphQLFactory {
@Bean
@Singleton
public GraphQL graphQL(ResourceResolver resourceResolver, HelloDataFetcher helloDataFetcher) { (2)
SchemaParser schemaParser = new SchemaParser();
SchemaGenerator schemaGenerator = new SchemaGenerator();
// Parse the schema.
TypeDefinitionRegistry typeRegistry = new TypeDefinitionRegistry();
typeRegistry.merge(schemaParser.parse(new BufferedReader(new InputStreamReader(
resourceResolver.getResourceAsStream("classpath:schema.graphqls").get()))));
// Create the runtime wiring.
RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring()
.type("Query", typeWiring -> typeWiring
.dataFetcher("hello", helloDataFetcher))
.build();
// Create the executable schema.
GraphQLSchema graphQLSchema = schemaGenerator.makeExecutableSchema(typeRegistry, runtimeWiring);
// Return the GraphQL bean.
return GraphQL.newGraphQL(graphQLSchema).build();
}
}
import graphql.GraphQL
import graphql.schema.idl.RuntimeWiring
import graphql.schema.idl.SchemaGenerator
import graphql.schema.idl.SchemaParser
import graphql.schema.idl.TypeDefinitionRegistry
import groovy.transform.CompileStatic
import io.micronaut.context.annotation.Bean
import io.micronaut.context.annotation.Factory
import io.micronaut.core.io.ResourceResolver
import javax.inject.Singleton
@Factory (1)
@CompileStatic
class GraphQLFactory {
@Bean
@Singleton
GraphQL graphQL(ResourceResolver resourceResolver, HelloDataFetcher helloDataFetcher) { (2)
def schemaParser = new SchemaParser()
def schemaGenerator = new SchemaGenerator()
// Parse the schema.
def typeRegistry = new TypeDefinitionRegistry()
typeRegistry.merge(schemaParser.parse(new BufferedReader(new InputStreamReader(
resourceResolver.getResourceAsStream("classpath:schema.graphqls").get()))))
// Create the runtime wiring.
def runtimeWiring = RuntimeWiring.newRuntimeWiring()
.type("Query", { typeWiring -> typeWiring
.dataFetcher("hello", helloDataFetcher) })
.build()
// Create the executable schema.
def graphQLSchema = schemaGenerator.makeExecutableSchema(typeRegistry, runtimeWiring)
// Return the GraphQL bean.
return GraphQL.newGraphQL(graphQLSchema).build()
}
}
import graphql.GraphQL
import graphql.schema.idl.RuntimeWiring
import graphql.schema.idl.SchemaGenerator
import graphql.schema.idl.SchemaParser
import graphql.schema.idl.TypeDefinitionRegistry
import io.micronaut.context.annotation.Bean
import io.micronaut.context.annotation.Factory
import io.micronaut.core.io.ResourceResolver
import java.io.BufferedReader
import java.io.InputStreamReader
import javax.inject.Singleton
@Factory (1)
class GraphQLFactory {
@Bean
@Singleton
fun graphQL(resourceResolver: ResourceResolver, helloDataFetcher: HelloDataFetcher): GraphQL { (2)
val schemaParser = SchemaParser()
val schemaGenerator = SchemaGenerator()
// Parse the schema.
val typeRegistry = TypeDefinitionRegistry();
typeRegistry.merge(schemaParser.parse(BufferedReader(InputStreamReader(
resourceResolver.getResourceAsStream("classpath:schema.graphqls").get()))))
// Create the runtime wiring.
val runtimeWiring = RuntimeWiring.newRuntimeWiring()
.type("Query") { typeWiring -> typeWiring
.dataFetcher("hello", helloDataFetcher) }
.build()
// Create the executable schema.
val graphQLSchema = schemaGenerator.makeExecutableSchema(typeRegistry, runtimeWiring)
// Return the GraphQL bean.
return GraphQL.newGraphQL(graphQLSchema).build()
}
}
1 | Define the Factory annotation to create the bean. |
2 | Define the GraphQL bean which contains the runtime wiring and the executable schema. |
There are various examples using different technologies provided in the repository.
2.2 Configuring GraphiQL
The micronaut-graphql
module comes bundled with GraphiQL, an in-browser IDE for exploring GraphQL.

GraphiQL must be explicitly enabled via the graphql.graphiql.enabled
application property.
The following configuration properties can be set:
graphql:
graphiql:
enabled: false (1)
version: 0.13.2 (2)
path: /graphiql (3)
template-path: classpath:graphiql/index.html (4)
template-parameters: (5)
page-title: GraphiQL (6)
1 | Enables/disables GraphiQL. Default false . |
2 | Configures the GraphiQL version. Default 0.13.2 . |
3 | Configures the GraphiQL endpoint path. Default /graphiql . |
4 | Configures the GraphiQL template path. Default classpath:graphiql/index.html . |
5 | Configures the GraphiQL template parameters. Default none. |
6 | Configures the GraphiQL page title. Default GraphiQL . |
The out of the box rendered GraphiQL page does not provide many customisations except the GraphiQL version, path and page title.
It also takes into account the graphql.path
application property,
to provide a seamless integration with the configured GraphQL endpoint path.
If further customisations are required, a custom GraphiQL
template
can be provided. Either by providing the custom template at src/main/resources/graphiq/index.html
or via the graphiql.template-path
application property pointing to a different template location.
In that case it could also be useful to dynamically replace additional parameters in the template via the graphql.graphiql.template-parameters
application property.