GraphQL in Play Framework
Tags: GraphQL, Java, Play Framework, Graphql Playground

Many different programming languages supports GraphQL. Java programming language also support for building GraphQL APIs. The basic understanding of GraphQL and play framework are the prerequisite requirement to understand the below explanation and an example can be found over on the github project which is a Java implementation of GraphQL API with Play framework.

Installation

Add the GraphQL dependency to your pom.xml or build.sbt if you’re using sbt build tool instead of Maven.

<dependency>

<groupId>com.graphql-java</groupId>

<artifactId>graphql-java</artifactId>

<version>15.0</version>

</dependency>

SBT:

libraryDependencies ++= Seq("com.graphql-java" % "graphql-java" % "15.0")

Define a GraphQL Schema(SDL):

type Query {productById(id: String!): Product}

type Product {

id: ID!

categoryName: String

description: String!

details: [ProductDetail!]

image: String!

instances: [ProductInstance!]

name: String!

related: [Product!]

}

type ProductDetail {

id: ID!

description: String

display: String

image: String

link: String

linkCaption: String

name: String!

type: String!

provisionAllowed: Boolean!

}

type ProductInstance {

id: ID

name: String

note: String

status: String

subscribedDate: String

}

Define a http request route:

The following line maps a POST request for the GraphQL URL /graphql to the postHandler action in GraphQLController : GET / controllers.GraphQLController.postHandler() Now modify the postHandler action method to execute the graphQL query. This method responsible to read the client query and prepare the GraphQL Executable input using the GraphQLRequest. Here is the sample snippet:

JsonNode body = request().body().asJson();

GraphQLRequest graphQLRequest = MAPPER.readValue(body.traverse(), GraphQLRequest.class);

Map<String,Object> variables = graphQLRequest.getVariables();

if (variables == null) {

variables = new HashMap<>();

}

ExecutionInput executionInput = ExecutionInput.newExecutionInput()

.query(graphQLRequest.getQuery())

.operationName(graphQLRequest.getOperationName())

.variables(variables)

.build();

First we have to prepare the graphql schema. The graphql schema depends on type definition registry and runtime wiring. Here type definition registry is created by parsing the “schema.graphqls” file and runtime wiring do the mapping with data fetcher and field definitions of SDL. here is the snippet of type definition registry:

ClassLoader classLoader = getClass().getClassLoader();

String path = URLDecoder.decode(classLoader.getResource("schema.graphqls").getFile(), "UTF-8");

TypeDefinitionRegistry typeRegistry = new graphql.schema.idl.SchemaParser().parse(new File(path));

This is how the runtime wiring defined which maps the Query type to the “productById” resolver and the “details”, “instance” and “related” field definition types are wired with the respective resolves in the “Product”.

RuntimeWiring.newRuntimeWiring()

.type(TypeRuntimeWiring.newTypeWiring("Query")

.dataFetcher("productById", productDataFetcher.productById()))

.type(TypeRuntimeWiring.newTypeWiring("Product")

.dataFetcher("details", productDataFetcher.productDetail())

.dataFetcher("instance", productDataFetcher.productInstance())

.dataFetcher("related", productDataFetcher.relatedOfferings()))

.build();

Now the GraphQL schema use the above defined type definition and runtime wiring and creates the GraphQLSchema:

GraphQLSchema schema = schemaGenerator.makeExecutableSchema(typeRegistry, runtimeWiring);

Now execute the input using the GraphQL schema and executableInput defined(above) using below snippet:

final CompletableFuture<ExecutionResult> executionResult = GraphQL.newGraphQL(schema).build().executeAsync(executionInput);

Let’s run this sample web application using the sbt build tool by running the “sbt run” command in terminal. Once this application become up successful, we can try GraphQL playground and run some queries.

Conclusion

This is just tip of the GraphQL iceberg. If you are interested in the more advanced features, feel free to take a look at the official GraphQL documentation.

Have fun!