Let's improve our schema-first GraphQL mocks by intercepting all GraphQL operations—both queries and mutations—using a single Mock Service Worker graphql.operation()
request handler.
Lecturer: [0:00] As our application grows and starts making more GraphQL requests, it would be great to resolve them against the same schema that we have. We can of course copy and paste the executeGraphql logic across different request handlers, but that won't be a scalable approach.
[0:14] Instead, we will migrate from GraphQL query and GraphQL mutation handlers to use graphql.operation. The GraphQL operation handler will intercept all GraphQL operations regardless of their type or name, and allow us to handle them using a single responseResolver function.
[0:33] Let's move the existing executeGraphql logic from our listReviews handler to the newly added operation handler. Just like the other responseResolvers for GraphQL, we will access the query and variables arguments on the responseResolver.
[0:47] Since the GraphQL operation handler will now also intercept the addReview mutation, let's define it in our schema so that GraphQL knows about it and can resolve it. Add a new mutation called addReview with arguments author and reviewInput.
[1:07] Next, define these userInput and reviewInput types. Now that our schema understands the addReview mutation, let's add a GraphQL resolver for it in the root value object in our handler.
[1:30] We will move the logic from the addReview request handler to this GraphQL resolver. Since this resolver executes in a GraphQL context, we can't really return any HTTP responses from it, so let's replace the error response with throwing a regular error and rely on GraphQL propagating this error to the response for us.
[1:58] In the same manner, instead of returning a successful response, we will return what the addReview mutation expects, the new review object.
[2:05] Finally, let's remove the previous GraphQL request handlers because we don't need them anymore. Both our query and mutation resolve against the actual GraphQL schema now, and so will any other GraphQL requests we may add in the future, all using a single GraphQL operation request handler.
I meant to say I have defined the type Review based on type Review in the schema and I'm referring to the data returned by executeGraphQL.
When I return it as return HttpResponse.json({ errors, data });
this is where I get the error because the expected response is just null | undefined
Hi! Please, do you have a reproduction repo I can look at? It's quite difficult to suggest anything by text alone. I'm sure we can figure this one out quickly and have your mocked response type-safe. Thanks.
Yes sir. msw-course
It occurred to me that this project for the course is for demo purposes of MSW and all of that is working so no problem there. My TS problem I think is in the useQuery hook where I'm a bit lost on the code. I also found that graphql.operations is generic so I can pass in the expected type to get that as the return type for 'data'. Now I just need to understand the code in useQuery and I should be able to work it out. Thanks
Note that you can pass query and variables type to graphql.operation()
as well!
graphql.operation<Query, Variables>(resolver)
Since this handler is meant to handle any GraphQL operations, make sure you provide a union of query and variables types to reflect that.
Give it a try, and if you encounter any difficulties, please reach out to me on GitHub: https://github.com/mswjs/msw/discussions. Thanks!
Is there a way to type annotate the returned data? I get the following error from ts
Shouldn't data be something like
Review | Array<Review>
and expand from there as we add to executeGraphQL? Also I'm having a hard time following the client side code to see where it is expectingnull | undefined
Thanks