GraphQL Orchestrator stitches the schemas from multiple micro-services and orchestrates the graphql queries to these services accurately at runtime
A powerful Java library for aggregating and executing GraphQL operations from multiple microservices using a single unified schema.
graphql-orchestrator-java simplifies the process of accessing data from various GraphQL microservices by providing a unified GraphQL schema. This enables you to query multiple microservices through a single endpoint, reducing complexity and improving performance.
The library supports two strategies to aggregate and combine the schemas from multiple microservices
@key, @requires, @extends, and @external
directives)At query execution time, it orchestrates the GraphQL queries to the appropriate micro-services, using the popular graphql-java library as the execution engine.
graphql-java
Instrumentation
<dependency>
<groupId>com.intuit.graphql</groupId>
<artifactId>graphql-orchestrator-java</artifactId>
<version>${graphql.orchestrator.version}</version>
</dependency>
Consider the following 2 service providers below
class PersonNameService implements ServiceProvider {
public static final String schema =
"type Query { person: Person } "
+ "type Person { firstName : String lastName: String }";
@Override
public String getNameSpace() { return "PERSON_NAME"; }
@Override
public Map<String, String> sdlFiles() { return ImmutableMap.of("schema.graphqls", schema); }
@Override
public CompletableFuture<Map<String, Object>> query(final ExecutionInput executionInput,
final GraphQLContext context) {
//{'data':{'person':{'firstName':'GraphQL Orchestrator', 'lastName': 'Java'}}}"
Map<String, Object> data = ImmutableMap
.of("data", ImmutableMap.of("person", ImmutableMap.of("firstName", "GraphQL Orchestrator", "lastName", "Java")));
return CompletableFuture.completedFuture(data);
}
}
class PersonAddressService implements ServiceProvider {
public static final String schema =
"type Query { person: Person }"
+ "type Person { address : Address }"
+ "type Address { city: String state: String zip: String}";
@Override
public String getNameSpace() { return "PERSON_ADDRESS";}
@Override
public Map<String, String> sdlFiles() { return ImmutableMap.of("schema.graphqls", schema);}
@Override
public CompletableFuture<Map<String, Object>> query(final ExecutionInput executionInput,
final GraphQLContext context) {
//{'data':{'person':{'address':{ 'city' 'San Diego', 'state': 'CA', 'zip': '92129' }}}}"
Map<String, Object> data = ImmutableMap
.of("data", ImmutableMap.of("person", ImmutableMap.of("address", ImmutableMap.of("city","San Diego", "state","CA", "zip","92129"))));
return CompletableFuture.completedFuture(data);
}
}
// create a runtimeGraph by stitching service providers
RuntimeGraph runtimeGraph = SchemaStitcher.newBuilder()
.service(new PersonNameService())
.service(new PersonAddressService())
.build()
.stitchGraph();
// pass the runtime graph to GraphQLOrchestrator
GraphQLOrchestrator graphQLOrchestrator = GraphQLOrchestrator.newOrchestrator()
.runtimeGraph(runtimeGraph).build();
//Execute the query
CompletableFuture<ExecutionResult> execute = graphQLOrchestrator
.execute(
ExecutionInput.newExecutionInput()
.query("query {person {firstName lastName address {city state zip}}}")
.build()
);
ExecutionResult executionResult = execute.get();
System.out.println(executionResult.getData().toString());
// Output:
// {person={firstName=GraphQL Orchestrator, lastName=Java, address={city=San Diego, state=CA, zip=92129}}}
The Orchestrator uses a recursive algorithm to combine the schemas from multiple services and generate the following unified schema.
type Query {
person: Person
}
type Person {
firstName: String
lastName: String
address: Address
}
type Address {
city: String
state: String
zip: String
}
Graph Quilt Gateway is a SpringBoot application that uses the graphql-orchestrator-java.
Detailed Documentation can be found here
If you are interested in contributing to this project, please read the CONTRIBUTING.md file for details on our code of conduct, and the process for submitting pull requests to us.
This project is licensed under the MIT License - see the LICENSE file for details.