We're using graphql-java to build a graphql server and having trouble conforming to the Relay spec. According to the Relay spec, all nodes must be retrievable via a single query: node(id: ID). The graphql-java docs show support for Relay's node interface, however documentation for actually implementing this is rather sparse. The exact issue we are encountering is understanding how to generate a generic lookup for the node query? The Relay Todo example: https://github.com/graphql-java/todomvc-relay-java shows an extremely simple code-based approach with a single datafetcher, the example here never needs to "read" the nodes "type" or delegate that request to the correct dataFetcher.
schema.graphqls:
type Query {
node(id: ID!): Node
user(id: ID!): User
otherType(id:ID!): OtherType
}
interface Node {
id: ID!
}
type User implements Node {
id: ID!
firstName: String
lastName: String
}
type OtherType implements Node {
id: ID!
description: String
stuff: String
}
We're currently using the SDL to generate our schema (as shown below)
@Bean
private GraphQLSchema schema() {
Url url = Resources.getResource("schema.graphqls");
String sdl = Resources.toString(url, Charsets.UTF_8);
GraphQLSchema graphQLSchema = buildSchema(sdl);
this.graphQL = GraphQL.newGraphQL(graphQLSchema).build();
return graphQLSchema;
}
private GraphQLSchema buildSchema(String sdl) {
TypeDefinitionRegistry typeRegistry - new SchemaParser().parse(sdl);
RuntimeWiring runtimeWiring = buildWiring();
SchemaGenerator schemaGenerator = new SchemaGenerator();
return schemaGenerator.makeExecutableSchema(typeRegistry, runtimeWiring);
}
private RuntimeWiring buildWiring(){
return RuntimeWiring.newRuntimeWiring()
.type(newTypeWiring("Query")
.dataFetcher("user", userDispatcher.getUserById()))
.type(newTypeWiring("Query")
.dataFetcher("otherType", otherTypeDispatcher.getOtherTypeById()))
.type(newTypeWiring("Query")
.dataFetcher("node", /*How do we implement this data fetcher? */))
.build()
}
Assumably, we would have to wire up a datafetcher as shown in the last line above. However, this is where the documentation starts to get hazy. Does the above conform to the Relay spec? How would we go about implementing a single node dataFetcher which returns back a reference to any single node, regardless of the underlying type (User, OtherType, etc)?
You are right, you need to implement a node data fetcher that will return a Node from a Node id.
I am going to assume you are using an underlying sql database: a Node could be of any type, and that means you cannot use the database id as a Node id (because two nodes of different types could have the same database id). You need to build your own Node id.
A simple way to build such an id is to concatenate the object type and the object id. Example: "User:4234".
As the relay graphql server specification specify:
We need to encode/decode the node id to base 64.
The code below has not been tested, but will give you an idea on how to proceed.