Running a GraphQL service
Visit armeria-examples to find a fully working example.
First, You need the armeria-graphql dependency:
- Gradle
- Gradle (Kotlin)
- Maven
dependencies {
implementation platform('com.linecorp.armeria:armeria-bom:1.34.1')
...
implementation 'com.linecorp.armeria:armeria-graphql'
}
dependencies {
implementation(platform("com.linecorp.armeria:armeria-bom:1.34.1"))
...
implementation("com.linecorp.armeria:armeria-graphql")
}
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.linecorp.armeria</groupId>
<artifactId>armeria-bom</artifactId>
<version>1.34.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
...
<dependency>
<groupId>com.linecorp.armeria</groupId>
<artifactId>armeria-graphql</artifactId>
</dependency>
</dependencies>
Let's assume we have the following GraphQL Schema:
type Query {
user(id: ID): User
}
type User {
id: ID
name: String
}
The schema describes that if a client requests a User data using the ID field, the GraphQL server will
return the User data. The GraphQL engine uses a DataFetcher
to resolve the ID and fetch the corresponding object. For the sake of simplicity, let's implement
UserDataFetcher that stores Users in a Map:
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
class UserDataFetcher implements DataFetcher<User> {
private final Map<String, User> data = Map.of("1", new User("1", "hero"),
"2", new User("2", "human"),
"3", new User("3", "droid"));
@Override
public User get(DataFetchingEnvironment environment) throws Exception {
final String id = environment.getArgument("id");
return data.get(id);
}
}
Please note that this is entirely based on graphql-java.
GraphqlService
Once you've finished the implementation of the DataFetcher, you need to build a GraphqlService using
a GraphqlServiceBuilder and add it to the ServerBuilder:
import com.linecorp.armeria.server.Server;
import com.linecorp.armeria.server.ServerBuilder;
import com.linecorp.armeria.server.graphql.GraphqlService;
ServerBuilder sb = Server.builder();
...
sb.service("/graphql",
GraphqlService.builder()
.runtimeWiring(c -> {
c.type("Query",
typeWiring -> typeWiring.dataFetcher("user", new UserDataFetcher()));
})
.build());
...
Server server = sb.build();
server.start();
We used RuntimeWiring to wire the type with DataFetcher. Please see Creating a schema using the SDL to find more wiring examples.
Blocking service implementation
Armeria does not run service logic in a separate thread pool by default. If your service implementation
requires blocking, either run the individual blocking logic in a thread pool, or set
GraphqlServiceBuilder.useBlockingTaskExecutor() to true so the service runs in
all service methods and lifecycle callbacks.
ServerBuilder sb = Server.builder();
sb.service("/graphql",
GraphqlService.builder()
.runtimeWiring(c -> {
c.type("Query",
typeWiring -> typeWiring.dataFetcher("user", new UserDataFetcher()));
})
// All service methods will be run within
// the blocking executor.
.useBlockingTaskExecutor(true)
.build());
You can wrap a DataFetcher using AsyncDataFetcher to run it asynchronously.