Have It Your Way With MicroProfile GraphQL
Have It Your Way With MicroProfile GraphQL
Int his article, see how easy it is to create GraphQL applications using a sample of MicroProfile GraphQL on OpenLiberty.
Join the DZone community and get the full member experience.Join For Free
GraphQL is a remote data access API that addresses issues like under-fetching and over-fetching that are inherent in most RESTful applications. It allows clients to specify the exact data they want - to "have it their way". If you would like to learn more about GraphQL, I recommend checking out the tutorial at GraphQL.org.
GraphQL applications use a schema that acts as a description of the data provided by the server and as a contract between the client and server. Most GraphQL programming models require developers to dual-maintain their schema and the application code that supports it. MicroProfile GraphQL takes a "code first" approach which allows developers to write Java code using annotations to mark GraphQL schema elements, and then the MicroProfile GraphQL implementation generates the schema at runtime.
In this blog post, we'll explore how easy it is to create GraphQL applications using this sample.
To set up your Maven environment for developing a MP GraphQL application, you'll need a dependency like:
I recommend using the Liberty Maven plugin, but it's not strictly necessary so long as you generate a Web Archive (WAR) file for deployment.
When configuring the Liberty server for deployment, make sure that the
featureManager element in the
server.xml file contains the
mpGraphQL-1.0 feature. For example:
mpMetrics-2.3 feature is not required, but will track the number of GraphQL query/mutation invocations and cumulative time when enabled.
Now that we've got things set up, let's look at the code.
Coding a MicroProfile GraphQL Application
A MicroProfile GraphQL application should have at least one root-level query and/or mutation. To create a query or mutation, you start with a public Java class annotated with
@GraphQLApi. Then you add public methods that are annotated with
@Mutation for query or mutation, respectively. The query/mutation methods must always return a non-void type. These methods can return simple types like
boolean, etc. which will be mapped to GraphQL scalars such as
Boolean, etc. Alternatively, these methods could return custom Java types - the types would be mapped to GraphQL types and defined in the generated schema. For more details, see the MicroProfile GraphQL 1.0.2 API Docs.
For example, in the sample application, the
currentConditions query method returns a type called
Conditions - that type has properties such as
weatherText, etc. The following schema is generated from the query and its return value:
currentConditions query has an argument, called
location. In the Java code, the argument is represented by a method parameter. Like output types, arguments/parameters can be simple Java types (mapping to GraphQL scalars) or custom types, which would be mapped to input types in the generated schema.
When mapping custom types, it is possible to change the name used in the schema by using the
@Name annotation. For example, if we wanted to change the schema to display
tempInFahrenheit instead of
temperatureF, we could just add
@Name("tempInFahrenheit") to the
temperatureF field in the
If your application uses JSON-B, then
@JsonbNumberFormat annotations can be used instead of
@NumberFormat. When both sets of annotations are used, the annotations from the MicroProfile GraphQL APIs take precedence over the JSON-B APIs when used for schema generation or query/mutation execution.
Another useful annotation is
@Source. This annotation can be used to add a field to an entity object that might be expensive to look up or calculate, and so you might not want to spend the resources on the server side to compute that field when the client doesn't want it anyway. Here's an example from the sample:
This example is a little contrived, but it shows us that the
wetBulbTempF field will only be computed if the client requests that field. This method is in a class annotated with
@GraphQLApi (in this example,
WeatherService) and it contains a parameter annotated with
@Source that takes the entity object,
Conditions. When a client issues a query or mutation that would return the
Conditions entity, and that query/mutation specifies the
wetBulbTempF field, the
wetBulbTempF(Conditions conditions) method is invoked by the GraphQL implementation, passing in the
Conditions object that was returned from the query/mutation method.
Running the MicroProfile GraphQL App
To run and test the GraphQL application, you simply need to deploy it as a WAR file. The Liberty Maven Plugin makes it easy to build, deploy, and test using Apache Maven. After you have cloned the sample from GitHub (
git clone [email protected] :OpenLiberty/sample-mp-graphql.git) or downloaded the source ZIP file, just run:
mvn clean package liberty:run
This builds, packages, and deploys the GraphQL application to the latest Open Liberty server runtime and starts the server and app. Then you can use the pre-packaged GraphiQL HTML interface to send queries or mutations at:
Here are a few sample queries and mutations that you could use to get started - you may see some interesting results:
Authorizing Access to Certain Queries/Mutations
It may be necessary to restrict access to certain queries/mutations to certain authenticated users. While it is not part of the MicroProfile GraphQL 1.0 specification (it is under consideration for a future version of the spec), Open Liberty makes authorization checks possible by using the
@RolesAllowed annotations. These annotations must be placed on the class or method of classes annotated with
When implementing authorization with MicroProfile GraphQL, you need to enable the
appSecurity-2.0) feature in the server configuration. You also need to set up the user registry and web container metadata for authentication and authorization.
In the sample, we use the basic user registry which defines two users, one for each of two roles:
This means that
user1 is part of
user2 is part of
web.xml declares these roles, and also sets up form-based authentication so that, when the Application Security feature is enabled, clients are prompted to log in using a web-based form before accessing the GraphiQL HTML page. It also allows the application to prevent users other than those in
Role2 to invoke the
reset mutation method:
Integration With MicroProfile Metrics
If you enable the
mpMetrics-2.3 feature with
mpGraphQL-1.0, Open Liberty tracks the number of times a particular query or mutation method is invoked-and the cumulative time spent in that method. These metrics can be useful for determining what data is being accessed, how often, and where time is spent in execution.
Metrics collection and reporting for GraphQL applications is not mentioned in either the MicroProfile GraphQL 1.0 spec or the MicroProfile Metrics 2.3 spec, so the actual stats are collected and reported under the "vendor" category. To see these stats, you can browse to:
The stats are prefixed with
vendor_mp_graphql_ and should look something like this:
GraphQL is a powerful and popular query language for remote data access. MicroProfile GraphQL makes it easy to develop GraphQL applications in Java.
Published at DZone with permission of Andy McCright , DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.