GraphQL
Overview
The Helidon GraphQL Server provides a framework for creating GraphQL applications that integrate with the Helidon WebServer. GraphQL is a query language to access server data. The Helidon GraphQL integration enables HTTP clients to issue queries over the network and retrieve data; it is an alternative to other protocols such as REST or GRPC.
Maven Coordinates
To enable GraphQL, add the following dependency to your project’s pom.xml (see
Managing Dependencies).
<dependency>
<groupId>io.helidon.webserver</groupId>
<artifactId>helidon-webserver-graphql</artifactId>
</dependency>
API
An instance of GraphQlService must be registered in the Helidon WebServer
routes to enable GraphQL support in your application. In addition, a GraphQL
schema needs to be specified to verify and execute queries.
The following code fragment creates an instance of GraphQlService, disables
authentication for the public example endpoint, and registers it in the Helidon
WebServer.
Config graphQlConfig = Services.get(Config.class).get("graphql");
InvocationHandler invocationHandler = InvocationHandler.builder()
.config(graphQlConfig)
.schema(buildSchema())
.build();
WebServer server = WebServer.builder()
.routing(r -> r.register(GraphQlService.builder()
.config(graphQlConfig)
.invocationHandler(invocationHandler)
.permitAll(true)
.build()))
.build();
By default, GraphQlService will reserve /graphql as the URI path to process
queries and require requests to be authenticated. Set permitAll to true only
for endpoints intended to be public. The buildSchema method creates the schema
and defines 2 types of queries for this application:
static GraphQLSchema buildSchema() {
String schema =
"""
type Query {
hello: String\s
helloInDifferentLanguages: [String]\s
}
""";
SchemaParser schemaParser = new SchemaParser();
TypeDefinitionRegistry typeDefinitionRegistry = schemaParser.parse(schema);
DataFetcher<List<String>> dataFetcher = env -> List.of(
"Bonjour",
"Hola",
"Zdravstvuyte",
"Nǐn hǎo",
"Salve",
"Gudday",
"Konnichiwa",
"Guten Tag");
RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring()
.type("Query", builder -> builder
.dataFetcher("hello", new StaticDataFetcher("world")))
.type("Query", builder -> builder
.dataFetcher("helloInDifferentLanguages", dataFetcher))
.build();
SchemaGenerator generator = new SchemaGenerator();
return generator.makeExecutableSchema(typeDefinitionRegistry, runtimeWiring);
}
The following is a description of each of these steps:
- Define the GraphQL schema.
- Create a
DataFetcherto return a list of hellos in different languages. - Wire up the
DataFetchers. - Generate the GraphQL schema.
Configuration
The following configuration keys can be used to set up integration with WebServer:
| Key | Default Value | Description |
|---|---|---|
graphql. | /graphql | Context that serves the GraphQL endpoint |
graphql. | /schema. | URI that serves the schema (under web context) |
graphql. | false | Whether GraphQL requests are permitted without authentication |
graphql. | Configuration of `Server |
The following configuration keys can be used to set up GraphQL invocation:
| Key | Default Value | Description |
|---|---|---|
graphql. | Server Error | Error message to send to caller in case of error |
graphql. | 100 |
Maximum GraphQL query depth. Must not be negative. Set to 0 to
disable the limit.
|
graphql. | 1000 |
Maximum GraphQL query complexity. Must not be negative. Set to 0
to disable the limit.
|
graphql. | Array of checked exception classes that should return default error message | |
graphql. | Array of unchecked exception classes that should return message to caller (instead of default error message) |
By default, GraphQL invocation rejects queries deeper than
graphql.max-query-depth or more complex than graphql.max-query-complexity.
Applications that intentionally serve deeper or more complex queries should tune
these limits for their schemas. Setting a limit to 0 restores the previous
unlimited behavior for that limit.
Examples
Using the schema defined in Section API, you can probe the following endpoints:
- Hello world endpointTerminal
curl -X POST http://127.0.0.1:PORT/graphql \ -d '{"query":"query { hello }"}'Response"data":{"hello":"world"}} - Hello in different languagesTerminal
curl -X POST http://127.0.0.1:PORT/graphql \ -d '{"query":"query { helloInDifferentLanguages }"}'Response{"data":{"helloInDifferentLanguages":["Bonjour","Hola","Zdravstvuyte","Nǐn hǎo","Salve","Gudday","Konnichiwa","Guten Tag"]}}