Docs
Getting Started
Duplicate Types

Duplicate Types

Stitching has two strategies for handling types duplicated across subschemas: an automatic merge strategy (default), and an older manual resolution strategy. You may select between these strategies using the mergeTypes option.

Automatic Merge

Types with the same name are automatically merged by default in GraphQL Tools v7. That means objects, interfaces, and input objects with the same name will consolidate their fields across subschemas, and unions/enums will consolidate all of their members. The combined gateway schema will then smartly delegate portions of a request to the proper origin subschema(s). See type merging guide for a comprehensive overview.

Automatic merging will only encounter conflicts on type descriptions and fields. By default, the final definition of a type or field found in the subschemas array is used, or a specific definition may be marked as canonical to prioritize it. You may customize all selection logic using typeMergingOptions; the following example prefers the first definition of each conflicting element found in the subschemas array:

import { stitchSchemas } from '@graphql-tools/stitch'
 
const gatewaySchema = stitchSchemas({
  subschemas: [
    // ...
  ],
  mergeTypes: true, // << default in v7
  typeMergingOptions: {
    // select a preferred type candidate to provide definitions:
    typeCandidateMerger: candidates => candidate[0],
    // and/or itemize the selection of other specific definitions:
    typeDescriptionsMerger: candidates => candidate[0].type.description,
    fieldConfigMerger: candidates => candidate[0].fieldConfig,
    inputFieldConfigMerger: candidates => candidate[0].inputFieldConfig,
    enumValueConfigMerger: candidates => candidate[0].enumValueConfig
  }
})

Merge Validations

The automatic merge strategy also validates the integrity of merged schemas. Validations may be set to error, warn, or off for the entire schema or scoped for specific types and fields:

import { stitchSchemas } from '@graphql-tools/stitch'
 
const gatewaySchema = stitchSchemas({
  subschemas: [
    // ...
  ],
  typeMergingOptions: {
    validationSettings: {
      validationLevel: 'error',
      strictNullComparison: false, // << gateway "String" may proxy subschema "String!"
      proxiableScalars: {
        ID: ['String'] // << gateway "ID" may proxy subschema "String"
      }
    },
    validationScopes: {
      // scope to specific element paths
      'User.id': {
        validationLevel: 'warn',
        strictNullComparison: true
      }
    }
  }
})

Note that schema coordinates in validationScopes defined in the Schema Coordinates RFC

Manual Resolution

By setting mergeTypes: false, only the final description and fields for a type found in the subschemas array will be used, and automated query planning will be disabled. You may manually resolve differences between conflicting types with an onTypeConflict handler:

import { stitchSchemas } from '@graphql-tools/stitch'
 
const gatewaySchema = stitchSchemas({
  subschemas: [
    // ...
  ],
  mergeTypes: false,
  onTypeConflict: (left, right, info) =>
    info.left.schema.version >= info.right.schema.version ? left : right
})