Are you working around the clock creating new REST endpoints for you clients? Are the requirements constantly changing? Use graphQL with micronaut and give more control to the client.
The graphQL website is a great place to start reading. Also the tutorial by micronaut on graphQL is very good. To get started with micronaut please take a look at this previous post on micronaut with kotlin.
In this post we are going to create a graphQL server with micronaut. The complete code can be found on github here.
Setup
We begin by creating a micronaut application via their cli.
mn create-app graphql-cat-api --build=maven
Now add the graphQL dependency.
<dependency>
<groupId>io.micronaut.graphql</groupId>
<artifactId>micronaut-graphql</artifactId>
</dependency>
And add the property to enable graphQL .
graphql:
enabled: true
The schema
The graphQL schema is the specification of the API. Here we want to enable the client to retrieve a cat (object) by providing its chip id. The schema looks like this.
type Query {
cat(chipId: String!): Cat
}
type Cat {
name: String
age: Int
}
The Query
type contains all the query operations we enable. It requires (see the !
symbol) a chip id and returns an object with a name and age.
To read more about the posibilities of a graphQL schema start here.
Queries
Up until now this looks very similar to a REST setup. The cool thing is that the client can construct their own queries on this schema. In this very small example the client could request the name of the cat by the following query.
query {
cat(chipId: "123") {
name
}
}
Or the age of another cat by this query.
query {
cat(chipId: "456") {
age
}
}
There are a lot more things the client can do with these queries in bigger schemas. Read more about it here.
The runtime
GraphQL also entails a runtime to execute these queries. It will fetch the data for all the fields specified in the query. These resolvers can be defined on an object level or on the separate field levels. Here we define a resolver for the Cat
object.
@Singleton
public class CatDataFetcher implements DataFetcher<CatDTO> {
@Override
public CatDTO get(DataFetchingEnvironment dataFetchingEnvironment) {
return new CatDTO("Fred", 4);
}
}
We implement the DataFetcher
interface from graphql-java
, where micronaut-graphql
is based upon, for our self-defined object CatDTO
. And return just mock data for the example.
Finally we wire everything together. We parse the schema from a file, setup the datafetcher for the cat
field and return a graphQL bean.
@Singleton
public GraphQL graphQL(ResourceResolver resourceResolver, CatDataFetcher catDataFetcher) {
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("cat", catDataFetcher))
.build();
// Create the executable schema.
GraphQLSchema graphQLSchema = schemaGenerator.makeExecutableSchema(typeRegistry, runtimeWiring);
// Return the GraphQL bean.
return GraphQL.newGraphQL(graphQLSchema).build();
}
The application is done, your first graphQL server is done!
Exploring
To get a feel for your new graphQL endpoint we add some properties to enable GraphiQL
, a web interface to interactively run queries.
graphql:
graphiql:
enabled: true
path: /graphiql
page-title: GraphiQL
Take a look and query away.

Hopefully you are now able to create your own graphQL with micronaut endpoint. Happy querying!