MicroProfile GraphQL

The Microprofile GraphQL APIs are an extension to Helidon MP to allow building of applications that can expose a GraphQL endpoint.

Experimental

The Helidon GraphQL feature is currently experimental and the APIs are subject to changes until GraphQL support is stabilized.

Maven Coordinates

To enable MicroProfile GraphQL add the following dependency to your project’s pom.xml (see Managing Dependencies).

<dependency>
    <groupId>io.helidon.microprofile.graphql</groupId>
    <artifactId>helidon-microprofile-graphql-server</artifactId>
</dependency>
Copied

About the MicroProfile GraphQL Specification

Helidon MP implements the MicroProfile GraphQL spec version 1.1.0. The spec prescribes how applications can be built to expose an endpoint for GraphQL. GraphQL is an open-source data query and manipulation language for APIs, and a runtime for fulfilling queries with existing data. It provides an alternative to, though not necessarily a replacement for, REST.

For more information on GraphQL see https://graphql.org/.

Getting Started

Defining your API

The MicroProfile GraphQL specification defines a number of key annotations to be used when writing a GraphQL endpoint:

  • @GraphQLApi - identifies a CDI Bean as a GraphQL Endpoint

  • @Query - identifies a method as returning specified fields for an object or collection of entities

  • @Mutation - identifies a method which creates, deletes or updates entities

Please see the Microprofile GraphQL spec for the full list of available annotations.

For example, the following defines a GraphQL endpoint with a number of queries and mutations that work against a fictional CustomerService service and Customer class.

Simple ContactGraphQLApi
@ApplicationScoped
@org.eclipse.microprofile.graphql.GraphQLApi
public class ContactGraphQLApi {

    @Inject
    private CustomerService customerService;

    @org.eclipse.microprofile.graphql.Query
    public Collection<Customer> findAllCustomers() {  
        return customerService.getAllCustomers();
    }

    @org.eclipse.microprofile.graphql.Query
    public Customer findCustomer(@Name("customerId") int id) {  
        return customerService.getCustomer(id);
    }

    @org.eclipse.microprofile.graphql.Query
    public Collection<Customer> findCustomersByName(@Name("name") String name) {  
        return customerService.getAllCustomers(name);
    }

    @org.eclipse.microprofile.graphql.Mutation
    public Contact createCustomer(@Name("customerId") int id,  
                                  @Name("name") String name,
                                  @Name("balance") float balance) {
        return customerService.createCustomer(id, name, balance);
    }
}

public class customer {
    private int id;
    @NonNull
    private String name;
    private float balance;

    // getters and setters omitted for brevity
}
Copied
  • a query with no-arguments that will return all Customers
  • a query that takes an argument to return a specific Customer
  • a query that optionally takes a name and returns a collection of Customers
  • a mutation that creates a Customer and returns the newly created Customer

The above would generate a GraphQL schema as shown below:

Sample GraphQL Schema
type Query {
   findAllCustomers: [Customer]
   findCustomer(customerId: Int!): Customer
   findCustomersByName(name: String): [Customers]
}

type Mutation {
   createCustomer(customerId: Int!, name: String!, balance: Float!): Customer
}

type Customer {
   id: Int!
   name: String!
   balance: Float
}
Copied

After application startup, a GraphQL schema will be generated from your annotated API classes and POJO’s and you will be able to access these via the URL’s described below.

Creating your entry-point

As per the instructions here ensure you have added a src/main/resources/META-INF/beans.xml file, so the CDI implementation can pick up your classes.

A Main class is not needed, you can configure io.helidon.microprofile.cdi.Main as the entry point.

Optionally, you can configure a custom entry point (such as when you need custom configuration setup).

Sample Entry-point
public class MyMain {
    public static void main(String[] args) {
        io.helidon.microprofile.cdi.Main.main(args);
    }
}
Copied

Building your application

As part of building your application, you must create a Jandex index using the jandex-maven-plugin for all API and POJO classes that are used.

Generate Jandex index
<plugin>
<groupId>org.jboss.jandex</groupId>
<artifactId>jandex-maven-plugin</artifactId>
<executions>
  <execution>
    <id>make-index</id>
  </execution>
</executions>
</plugin>
Copied

Accessing the GraphQL end-points

After starting your application you should see a message similar to the following indicating the GraphQL support is available:

Sample Startup output
2020.11.16 12:29:58 INFO io.helidon.common.HelidonFeatures Thread[features-thread,5,main]: Helidon MP 2.1.1-SNAPSHOT features: [CDI, Config, Fault Tolerance, GraphQL, Health, JAX-RS, Metrics, Open API, Security, Server, Tracing]
2020.11.16 12:29:58 INFO io.helidon.common.HelidonFeatures.experimental Thread[features-thread,5,main]: You are using experimental features. These APIs may change, please follow changelog!
2020.11.16 12:29:58 INFO io.helidon.common.HelidonFeatures.experimental Thread[features-thread,5,main]: 	Experimental feature: GraphQL (GraphQL)
Copied

You can then use your GraphQL client via the default endpoint http://host:port/graphql.

The GraphQL Schema is available via http://host:port/graphql/schema.graphql.

If you wish to use the GraphiQL UI (https://github.com/graphql/graphiql) then please see the Helidon Microprofile GraphQL example at the following URL: https://github.com/oracle/helidon/tree/master/examples/microprofile/graphql

Configuration Options

MicroProfile GraphQL

The specification defines the following configuration options:

keydefault valuedescription
mp.graphql.defaultErrorMessageServer ErrorError message to send to caller in case of error
mp.graphql.exceptionsBlackList Array of checked exception classes that should return default error message
mp.graphql.exceptionsWhiteList Array of unchecked exception classes that should return message to caller (instead of default error message)

These configuration options are more significant that the configuration options that can be used to configure GraphQL invocation (see below).

Helidon GraphQL

In addition, we provide the following configuration options:

The following configuration keys can be used to set up integration with WebServer:

keydefault valuedescription
graphql.web-context/graphqlContext that serves the GraphQL endpoint.
graphql.schema-uri/schema.graphqlURI that serves the schema (under web context)
graphql.cors CORS configuration for this service
graphql.executor-service Configuration of ServerThreadPoolSupplier used to set up executor service

The following configuration keys can be used to set up GraphQL invocation:

keydefault valuedescription
graphql.default-error-messageServer ErrorError message to send to caller in case of error
graphql.exception-white-list Array of checked exception classes that should return default error message
graphql.exception-black-list Array of unchecked exception classes that should return message to caller (instead of default error message)