I've got a collection of graphql services that are combined together in a gateway using graphql-tools
schema stitching.
Here's some sample code for reference:
async function makeGatewaySchema() {
// define the remote executors, introspect the subschemas, etc.
return stitchSchemas({
subschemas: [
{
schema: postSubschema,
executor: postExecutor,
batch: true,
},
{
schema: userSubschema,
executor: userExecutor,
batch: true,
},
],
typeDefs: `
...
extend type User {
posts: [Post]
batchPostsJSON: JSON
batchPosts: [Post]
}
...
`,
resolvers: {
User: {
posts: {
selectionSet: "{ id }",
resolve(user, args, context, info) {
return delegateToSchema({
schema: schemaPost,
operation: "query",
fieldName: "postsByUserId",
args: { id: user.id },
context,
info,
});
},
},
batchPostsJSON: {
selectionSet: "{ id }",
resolve(user, args, context, info) {
return batchDelegateToSchema({
schema: schemaFavorite,
operation: "query",
fieldName: "postsByUserIds",
key: user.id,
argsFromKeys: (ids) => ({ ids }),
valuesFromResults: (results, keys) => {
return keys.map((id) => {
return results.filter((f) => f.user_id === id);
});
},
context,
info,
});
},
},
batchPosts: {
selectionSet: "{ id }",
resolve(user, args, context, info) {
return batchDelegateToSchema({
schema: schemaPost,
operation: "query",
fieldName: "postsByUserIds",
key: user.id,
argsFromKeys: (ids) => ({ ids }),
valuesFromResults: (results, keys) => {
// doesn't matter, we don't get here
},
context,
info,
});
},
},
},
},
});
}
In the example code above, I have three ways to get posts associated with a user:
1: User.posts
This works fine but isn't batched
2: User.batchPostsJSON
This is batched very nicely and works perfectly with one problem: the JSON
return type doesn't allow me to query Post
fields - I just get all of them no matter what. Worse, if Post
was related to some third type, I wouldn't be able to follow that relationship.
3: User.batchPosts
This allows me to query fields of Post
, but throws an exception - I've defined the return type as array of Post
, but JSON
is what comes back and I get an error in the gateway.
Is there a way to handle the JSON returned by the subschema and pretend that I'm really getting [Post]
back instead? By the time my valueFromResults
is finished, that IS what it will look like. The problem is that the return type mismatch between my typedef and the actual resolver throws an error before I have the chance to reformat the return value.