-
-
Notifications
You must be signed in to change notification settings - Fork 831
Description
Is your feature request related to a problem? Please describe.
Unable (or do not know how) to specify a selectionSet on a subschema when using batchDelegateToSchema
(not sure about delegateToSchema
yet). In my specific situation, I need to implement a custom valuesFromResults
which requires a specific field to be present on the results
, regardless if the client requested that field or not. I will provide an example below.
Describe the solution you'd like
On the selection set string, I was expecting to be able to select sub-objects without having to build the entire SelectionSetNode
. If I did need to build the node, I was unable to find a straightforward way of dynamically building that in combination with what the client is requesting.
Describe alternatives you've considered
I looked into implementing selectionSet
on batchDelegateToSchema
, but it seemed pretty burdensome to have to build the full SelectionSetNode
object (combining what is always required with what the client requested). It is possible there is a simple way of doing this that I was unable to locate.
Additional context
Code Sample showcasing this. Querying allPosts
without requesting user.id
should replicate the issue.
import { batchDelegateToSchema } from '@graphql-tools/batch-delegate';
import { makeExecutableSchema } from '@graphql-tools/schema';
import { stitchSchemas } from '@graphql-tools/stitch';
import { OperationTypeNode } from 'graphql';
interface Post {
id: string;
text: string;
userId: string;
user: User;
}
interface User {
id: string;
email: string;
}
const postSchema = makeExecutableSchema({
typeDefs: /* GraphQL */ `
type Post {
id: ID!
text: String
userId: ID!
}
type Query {
allPosts: [Post]
}
`,
resolvers: {
Query: {
allPosts() {
return [
{
id: '1',
text: 'my post 1',
userId: 'userId1',
},
{
id: '2',
text: 'my post 2',
userId: 'userId2',
},
];
},
},
},
});
const userSchema = makeExecutableSchema({
typeDefs: /* GraphQL */ `
type User {
id: ID!
email: String
}
type Query {
usersByIds(ids: [ID!]!): [User]
}
`,
resolvers: {
Query: {
usersByIds(_, args) {
return args.ids
.map((id: string) => {
return {
id: id,
email: `${id}@email.com`,
};
})
.reverse(); // Reversing so a valuesFromResults is required to implement
},
},
},
});
// setup subschema config objects
const postsSubschema = { schema: postSchema };
const usersSubschema = { schema: userSchema };
export const experimentSchema = stitchSchemas({
subschemas: [postsSubschema, usersSubschema],
typeDefs: /* GraphQL */ `
extend type Post {
user: User!
}
`,
resolvers: {
Post: {
user: {
selectionSet: `{ userId }`, // Thought I could maybe write { userId user { id} } to force "id" to be requested
resolve(post: Post, args, context, info) {
return batchDelegateToSchema({
schema: usersSubschema,
operation: OperationTypeNode.QUERY,
fieldName: 'usersByIds',
key: post.userId,
argsFromKeys: (ids) => ({ ids }),
valuesFromResults(results: User[], keys) {
return keys.map((key) =>
results.find((result) => result.id === key) // "id" is required, regardless if client requests it
);
},
context,
info,
});
},
},
},
},
});