Adding a field to a delegated GraphQL Request

Recently I've been working a lot with GraphQL services and schema stitching, and ran into a problem with delegated queries not returning the data that my code needed unless the user requested it. I found a way to add a transform to the delegateToSchema call to ensure that the data you need is present.

When working with non-stitched schemas, it's possible to ensure field resolution via a fragment on your resolver like this: fragment: '...on MyType { id }' which ensures that the id field will be populated on the rootValue argument for your resolver function, even if the query being made does not include it.

When delegating requests to a remote schema, there is no way to add a fragment style helper onto the delegation, which means if you need to map the returned data it is possible to be missing the key you need to do mapping with.

DataLoader is a great example of where this can happen, because it requires your data to be returned in the exact same order that it was provided in the ids argument. If your returned data does not have the id field on it though, you have no way to ensure that the returned order matches the order of the arguments.

Enter the little transform function below, AddFieldToDelegatedRequest. It can be used to inject a field to a delegated request if it is not already in the query that is being run, so that you can ensure that the id field you need to map the data internally will be returned, even if the end user is not requesting it.

Below is an example of how this transform function would be used in a DataLoader function that delegates to an external schema.

This snippet ensures that MyType will always have the id field resolved from the delegation call, even if the query is not requesting it. Ensuring this id field exists allows our order mapping function to succeed and ensure that the return order is consistent with the order the ids were passed into the arguments.