Getting started with micronaut and GraphQL

Table of Content

In this tutorial I will explain step-by-step how to get started with your first Hello World micronaut project with hot-reload and GraphQL API.

What you need:

  • a JDK; we use OpenJDK-11
  • micronaut in your PATH (for the mn-command; version 1.2.5)
  • a Text-Editor or a source-code-editor like Visual Studio Code
  • a terminal in which you can enter your commands (Visual Studio Code already ships with a terminal)

Recommended VSCode-extensions for Java:

  • Debugger for Java (Microsoft)
  • Gradle Tasks (Richard Willis)
  • Java Dependency Viewer (Microsoft)
  • Java Extension Pack (Microsoft)
  • Java Test Runner (Microsoft)
  • Language Support for Java(TM) by Red Hat (Red Hat)

Step 1: Create a micronaut project

To create a micronaut project, we have to execute the mn command.
This command will generate a project-folder in the folder you are executing it.
Open up your prompt and navigate to the folder in which you want to generate the project and execute:

$ mn create-app com.example.getting-started-with-micronaut-and-graphql --features file-watch
$ cd getting-started-with-micronaut-and-graphql

This command creates a project-folder with the name getting-started-with-micronaut-and-graphql and uses com.example as the default package for our application.
Additionally, we are adding the file-watch-feature which will be needed for hot-reload.
It will watch for file-changes in the src/main-folder, stop our app (how to automatically restart we will see later).

Step 2: Add GraphQL

To use GraphQL in our example, we first need to add it to our dependencies. Add this line in your dependencies-section of your gradle.build.

implementation "io.micronaut.graphql:micronaut-graphql"

And don’t forget to add options.incremental = false to the tasks.withType(JavaCompile)-section to have a fully functional hot-reloadable project.

Add this to your application.yml in your src/main/resources-folder.

graphql:
  enabled: true
  path: /api
  graphiql:
    enabled: true

It will enable GraphQL and set the path to /api. Additionally we enable GraphiQL to have a Web-Interface in which we can test our API.

Step 3: Schema, Datafetcher, and GraphQL-Factory

Now we can implement our GraphQL-API.

First, we create a schema, which will be used for our requests. In the folder src/main/resources create a file called schema.graphqls.

type Query {
    hello(name: String): String!
}

This query has a name-argument and returns a String.

To get data (e.g. from a database), we need a DataFetcher.
In the folder src/main/java/com/example create a file with the name HelloDataFetcher.java and paste this content.

package com.example;

import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;

import javax.inject.Singleton;

@Singleton
public class HelloDataFetcher implements DataFetcher<String> {

    @Override
    public String get(DataFetchingEnvironment env) {
        String name = env.getArgument("name");
        if (name == null || name.trim().length() == 0) {
            name = "World";
        }
        return "Hello " + name + "!";
    }
}

The get-method will get the data associated with the hello-query. As you can see it gets the argument with the name name and returns it with a Hello name! or if the name is empty a Hello World!.

Now as we have created the fetcher and our schema, we can proceed in creating the GraphQLFactory.

In the folder src/main/java/com/example create a file with the name GraphQLFactory.java and paste this content.

package com.example;

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) { 

        // create Parser
        SchemaParser schemaParser = new SchemaParser();

        // create Generator
        SchemaGenerator schemaGenerator = new SchemaGenerator();

        // create TypeDefinitionRegistry
        TypeDefinitionRegistry typeRegistry = new TypeDefinitionRegistry();

        // gets our GraphQL-Schema-Definition-File
        typeRegistry.merge(schemaParser.parse(new BufferedReader(new InputStreamReader(
                resourceResolver.getResourceAsStream("classpath:schema.graphqls").get()))));

        // Connects the hello-query with the hello-DataFetcher
        RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring()
                .type("Query", typeWiring -> typeWiring
                        .dataFetcher("hello", helloDataFetcher))
                .build();

        // creates the schema for our api
        GraphQLSchema graphQLSchema = schemaGenerator.makeExecutableSchema(typeRegistry, runtimeWiring);

        // creates our GraphQL-API by providing the schema
        return GraphQL.newGraphQL(graphQLSchema).build();
    }
}

Step 4: Testing with GraphiQL

Run the example with:

$ gradlew run --continuous

And navigate your browser to http://localhost:8080/graphiql

In the left textarea enter the following query:

{
  hello
}

You will see the following output:

{
  "data": {
    "hello": "Hello World!"
  }
}

Now let’s test the argument with

{
  hello(name: "Alice")
}

You will see the following output:

{
  "data": {
    "hello": "Hello Alice!"
  }
}

That’s it.

Best Page Builder Plugin
Best Digital Asset Library
Find amazing stock images
Feel free to leave a comment
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x