Type Merging Transform
GraphQL Mesh v0 documentation (superseded by v1): GraphQL Mesh enables the combination of multiple APIs with its type-merging transform. Merge types from various sources using Schema Stitching, preventing N+1 problems for requests. #GraphQL #Mesh
Type Merge transforms allow you to combine multiple sources by merging a type from each source, by using the Type Merging approach of Schema Stitching.
For example, you could combine responses from two different APIs on a single field, provided you rename the fields you want to stitch to the same name.
Installation
What is Type Merging?
Take an example Mesh Gateway with two different GraphQL sources Books and Authors, defined as
follows:
And you renamed AuthorWithBooks to Author using Rename transform.
then you expect the following query to work fine;
But it won’t work because Mesh doesn’t know which field belongs to which entity and how to combine
them. You could add additionalResolvers to extract books from AuthorWithBooks and then return
it as books field of Author type, but this adds a lot of overhead. So, let’s try Type Merging
here.
We have Type Merging transform to teach Mesh how to fetch entities from different sources:
Then now, our query will work as expected!
Prevent N+1 problem with Type Merging
The example above works fine, but there is an N+1 problem. It sends n requests for n entities.
But we have authors and books. Type Merging is smart enough to handle batching if you point it
to a field that returns a list of entities. Let’s update our configuration for this:
And now it batches the requests to the inner sources.
Using the Type Merging Transform
Config API Reference
types(type:Array of Object, required):typeName(type:String) - Name of the type (Query by default)key(type:Object) - Specifies a base selection set needed to merge the annotated type across subschemas. Analogous to theselectionSetsetting specified in merged type configuration.:selectionSet(type:String, required)
canonical(type:Boolean) - Specifies types and fields that provide a canonical definition to be built into the gateway schema. Useful for selecting preferred characteristics among types and fields that overlap across subschemas. Root fields marked as canonical specify which subschema the field proxies for new queries entering the graph.fields(type:Array of Object, required):fieldName(type:String, required)computed(type:Object) - specifies a selection of fields required from other services to compute the value of this field. These additional fields are only selected when the computed field is requested. Analogous to computed field in merged type configuration. Computed field dependencies must be sent into the subservice using an object key.:selectionSet(type:String, required)
queryFields(type:Array of Object, required) - Denotes a root field used to query a merged type across services. The marked field’s name is analogous to the fieldName setting in merged type configuration, while the field’s arguments and return type are used to infer merge configuration. Directive arguments tune the merge behavior:queryFieldName(type:String, required)keyField(type:String) - Specifies the name of a field to pick off origin objects as the key value. When omitted, a@keydirective must be included on the return type’s definition to be built into an object key. https://www.graphql-tools.com/docs/stitch-directives-sdl#object-keyskeyArg(type:String) - Specifies which field argument receives the merge key. This may be omitted for fields with only one argument where the recipient can be inferred.additionalArgs(type:String) - Specifies a string of additional keys and values to apply to other arguments, formatted as\"\"\" arg1: "value", arg2: "value" \"\"\".key(type:Array of String, required) - Advanced use only; Allows building a custom key just for the argument from the selectionSet included by the@keydirective.argsExpr(type:String) - Advanced use only; This argument specifies a string expression that allows more customization of the input arguments. Rules for evaluation of this argument are as follows:
- basic object parsing of the input key:
"arg1: $key.arg1, arg2: $key.arg2" - any expression enclosed by double brackets will be evaluated once for each of the requested keys, and then sent as a list:
"input: { keys: [[$key]] }" - selections from the key can be referenced by using the $ sign and dot notation:
"upcs: [[$key.upc]]", so that$key.upcrefers to theupcfield of the key.
additionalConfiguration(type:Any) - The path to a code file that has additional type merging configuration