Use default resolver/type resolver for non-nullable field in Apollo in TypeScript

137 Views Asked by At

I'm using @graphql-codegen/cli to create a GraphQL API with Apollo. The resolvers are written in TypeScript. I cannot figure out how to use a default resolver to resolve non-nullable fields. The problem is that TypeScript seems to need me to provide values for all non-nullable fields in the main resolver, which means the default resolvers don't get used.

My GraphQL:

type Post {
  id: ID!
  body: String!
}
input PostsRequest {
  start: Int
  end: Int
  cursor: Int
}

type PostsResponse {
  posts: [Post!]!
  totalCount: Int!
}

extend type Query {
  posts(request: PostsRequest!): PostsResponse!
}

PostsResponse will never be null, nor will either of its fields. My resolvers are these:

export const PostsResolver: Resolvers<{ query: { value: number } }> = {
  Query: {
    posts: (_, { request: { start, end } }, context = { query: { value: 4 } }) => {
      const query = constructQuery(start ?? 0, end ?? 5);

      context.query = query;
      return {
        totalCount: -1,
        posts: [{ id: "-1", body: "you should never see this!" }],
      };
    },
  },
  PostsResponse: {
    posts: (_1, _2, context) => {
      const results = executeQuery(context.query);
      return results.map((result) => ({ id: result.id, body: "you should never see this!" }));
    },
    totalCount: (_1, _2, context) => executeCount(context.query),
  },
  Post: {
    body: (post) => getPostBody(post.id),
  },
};

This returns "you should never see this!" as all post bodies, instead of what is returned by getPostBody(). How can I get the default resolver to execute in the above code?

1

There are 1 best solutions below

0
Michel Floyd On

This should be as simple as removing the line:

posts: [{ id: "-1", body: "you should never see this!" }],

With this missing from the posts resolver GraphQL will go looking for it under your PostResponse resolver.

There you have:

return results.map((result) => ({ id: result.id, body: "you should never see this!" }));

Replace this with:

return results.map((result) => ({ id: result.id} ));

Now the resolver will fall through to your Post resolver which will return the body.