0
votes

I know this has been asked a couple of times before, but I have found no definitive solution to whether this is possible with GraphQL. And I have a strong feeling this should be possible as it should be relatively easy to implement due to GraphQL queries running sequentially in Apollo.

I have a situation where I'm doing a GraphQL mutation first on the client, and then immediately after doing a query which uses the results from the previous query. This causes a needlessly long response time waiting for the server to respond to both requests. The requests look like this:

mutation createWebSession($authId: ID!) {
  webSession: createWebSession(authId: $authId) {
    token
    userId
  }
}

query listUserPaymentMethods($userId: ID!) {
  userPaymentMethods: paymentMethods(userId: $userId) {
    id
  }
}

I know that one simple band-aid solution to avoid making 2 round trips to the server is creating a new single GraphQL mutation endpoint that does both services on the back end. But that seems to defeat the purpose of writing modular, reusable GraphQL endpoints. As such, I'm curious if someone knows if Apollo GraphQL supports a cleaner way to chain 2 requests in which the results from the previous one are available to the next one as inputs.

Any help would be greatly appreciated, thanks.

1

1 Answers

5
votes

This is a limitation that specific to GraphQL in general. There is no way to do this in a single request for a couple of reasons:

  • While a GraphQL document may include any number of operations, only a single operation will be executed. If a document includes multiple operations, all operations must be named and the request must include an operationName parameter that specifies which operation to execute. In other words, while you can combine multiple queries into a single operation, or multiple mutations into a single operation, you cannot cannot mix-and-match queries and mutations.

  • Given any two fields that share the same "parent" field, both fields will resolve at the same time. The only exception to this are root level mutation fields, which do resolve in sequence. As such, GraphQL does not support any syntax that would let you reference another field and use it as the input to some argument.

One possible workaround is to include a field in your createWebSession payload type whose field is the Query type. I illustrate this approach in this article as a means of refetching queries but it would work for what you're trying to do as well.