As you may know, GlassFish 5.1 has been recently released. This is the first Jakarta EE release of GlassFish. I’ve taken this opportunity to deploy an application mixing GraphQL spqr and JNoSQL (backed by MongoDB) on it. And guess what? It works!
This is a preliminary work for the MicroProfile GraphQL initiative that has just started where spqr will be used as a basis.
This article explains the why and the how. If you want to dive into the technical details the code is available on GitHub. Everything is detailed in the README.
Using GraphQL spqr with CDI
This project is based on the graphql-java tutorial from Bojan Tomic.
The use case is the same: a basic HackerNews implementation with three domain objects: Link, User and Vote.
The use of GraphQL is deliberately basic and the emphasis is on CDI integration.
spqr enables to generate a GraphQL schema following a “code-first approach” where the schema is not predefined but is dynamically generated from annotated classes. A code-first implementation makes sense for a strongly-typed language such as Java by avoiding duplication between the schema and the classes.
In this example, 3 kinds of classes are annotated:
- Query: this is the facade for all GraphQL queries. Its methods are annotated with @GraphQLQuery,
- Mutation: this is the facade for all GraphQL mutations. Its methods are annotated with @GraphQLMutation and @GraphQLArgument,
- Resolvers: which are in charge of retrieving data for non-scalar types.Their methods are annotated with @GraphQLQuery and @GraphQLContext.
I’ve tried to maximize spqr integration with CDI. First of all, Query, Mutation, AuthData, repositories and resolvers are standard CDI beans, so that they can easily be injected in other components.
The mechanism to detect GraphQL classes and generate the schema is generic and is implemented as a CDI extension. CDI extension is a standard mechanism to interact with the CDI container through some specific life cycle events: ProcessAnntotatedType, ProcessBean, AfterBeanDiscovery etc … This enables to enrich the CDI meta-model by dynamically adding beans, parameters, annotations etc …
All the CDI magic is detailed in the README and isolated in the cdi subpackage.
I’ve decided to use JNoSQL to implement the repositories. As mentioned in my previous post, JNoSQL will be the basis for the first Jakarta EE specification. Mixing spqr and JNoSQL in a same project is an illustration of the future of Jakarta EE and MicroProfile.
Using JNoSQL impacts:
- the repository classes where the code is significantly simplified,
- the entity classes which are annotated à la JPA.
How to run the application
First off, there must be a running MongoDB instance accessible on standard TCP-IP port 27017.
Build the project and deploy the war file with your favorite IDE and runtime.
GraphiQL is used to access the application and is set as main page (index.html). GraphIQL enables to discover the schema and to run GraphQL queries from a broswer.
The project has been developed with OpenJDK-OpenJ9 1.8.0_192 and Payara-5.184.
It has also been successfully tested with:
- Glassfish 5.1,
- OpenLiberty 184.108.40.206,
- TomEE Plus 8.0.0.M1,
- Wildfly 15.0.1.
Playing with the application
Once you have deployed the war file to your favorite application server, you can play with the application by:
- Creating a user,
- Signing in a user,
- Listing all users,
- Creating a link
- Voting for a link
- Listing all votes.
Everything is detailed on GitHub.
Conclusion and next steps
This project demonstrates how to integrate spqr with CDI and JNoSQL on a very simple use case. It is far from using all GraphQL subtleties (fragment, data loader, subscription …), but it is a first and encouraging step : it works on all major Java EE 8 and MicroProfile platforms, including GlassFish 5.1!
The result seems promising but we do think that we can go a step forward in terms of integration and developer experience for real life projects. That’s why we have started the MicroProfile GraphQL initiative. We want to achieve something similar to JAX-RS with a high level of integration with Jakarta EE and MicroProfile. And, we are very happy to have been approved to move to the MicroProfile sandbox for further development.