Micronaut GraphQL Integration

Extensions to integrate Micronaut and GraphQL

Version: 1.0.0.BUILD-SNAPSHOT

1 Introduction

Micronaut supports GraphQL via the micronaut-graphql module.

2 Configuration

Micronaut 1.0.3 or above is required and you must have the micronaut-graphql dependency on your classpath:

build.gradle
compile "io.micronaut.graphql:micronaut-graphql:1.0.0.BUILD-SNAPSHOT"
pom.xml
<dependency>
    <groupId>io.micronaut.graphql</groupId>
    <artifactId>micronaut-graphql</artifactId>
    <version>{version}</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 with query, operationName and variables query parameters. The variables query parameter must be json encoded.

  • POST request with application/json body and keys query (String), operationName (String) and variables (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.

src/main/resources/application.yml
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.

GraphQLFactory.java
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
public class GraphQLFactory {

    @Bean
    @Singleton
    public GraphQL graphQL(ResourceResolver resourceResolver, HelloDataFetcher helloDataFetcher) {

        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()
                .scalar(...)
                .type("Query", typeWiring -> typeWiring
                        .dataFetcher(...))
                ...
                .build();

        // Create the executable schema.
        GraphQLSchema graphQLSchema = schemaGenerator.makeExecutableSchema(typeRegistry, runtimeWiring);

        // Return the GraphQL bean.
        return GraphQL.newGraphQL(graphQLSchema).build();
    }
}

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

GraphiQL must be explicitly enabled via the graphql.graphiql.enabled application property.

The following configuration properties can be set:

src/main/resources/application.yml
graphql:
  graphiql:
    enabled: false (1)
    path: /graphiql (2)
    template-path: classpath:graphiql/index.html (3)
    template-parameters: (4)
    page-title: GraphiQL (5)
1 Enables/disables GraphiQL. Default false.
2 Configures the GraphiQL endpoint path. Default /graphiql.
3 Configures the GraphiQL template path. Default classpath:graphiql/index.html.
4 Configures the GraphiQL template parameters. Default none.
5 Configures the GraphiQL page title. Default GraphiQL.

The out of the box rendered GraphiQL page does not provide many customisations except the GraphiQL 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.