Migration to v7
Upgrading from v6
If you are using GraphQL Tools v6, there are several breaking changes to be aware of.
Schema Generation and Decoration API (@graphql-tools/schema
)
-
Resolver validation options should now be set to
error
,warn
orignore
rather thantrue
orfalse
. In previous versions, some validators caused errors to be thrown, while some issued warnings. This change brings consistency to validator behavior. -
The
allowResolversNotInSchema
has been renamed torequireResolversToMatchSchema
, to harmonize the naming convention of all the validators. The default setting ofrequireResolversToMatchSchema
iserror
, matching the previous behavior.
Schema Delegation (delegateToSchema
& @graphql-tools/delegate
)
-
The
delegateToSchema
return value has matured and been formalized as anExternalObject
, in which all errors are integrated into the GraphQL response, preserving their initial path. Those advanced users accessing the result directly will note the change in error handling. This also allows for the deprecation of unnecessary helper functions includingslicedError
,getErrors
,getErrorsByPathSegment
functions. Only external errors with missing or invalid paths must still be preserved by annotating the remote object with special properties. The newgetUnpathedErrors
function is therefore necessary for retrieving only these errors. Note also the newannotateExternalObject
andmergeExternalObjects
functions, as well as the renaming ofhandleResult
toresolveExternalValue
. -
Transform types and the
applySchemaTransforms
are now relocated to thedelegate
package;applyRequestTransforms
/applyResultTransforms
functions have been deprecated, however, as this functionality has been replaced since v6 by theTransformer
abstraction. -
The
transformRequest
/transformResult
methods are now provided additionaldelegationContext
andtransformationContext
arguments — these were introduced in v6, but previously optional. -
The
transformSchema
method may wish to create additional delegating resolvers and so it is now provided thesubschemaConfig
and final (non-executable)transformedSchema
parameters. As in v6, thetransformSchema
is kicked off once to produce the non-executable version, and then, if a wrapping schema is being generated, proxying resolvers are created with access to the (non-executable) initial result. In v7, the individualtransformSchema
methods also get access to the result of the first run, if necessary, they can create additional wrapping schema proxying resolvers. -
applySchemaTransforms
parameters have been updated to match and support thetransformSchema
parameters above.
Remote Schemas & Wrapping (wrapSchema
, makeRemoteExecutableSchema
, and @graphql-tools/wrap
)
-
wrapSchema
andgenerateProxyingResolvers
now only take a single options argument with named properties of typeSubschemaConfig
. The previously possible shorthand version with the first argument consisting of aGraphQLSchema
and the second argument representing the transforms should be reworked as aSubschemaConfig
object. -
Similarly, the
ICreateProxyingResolverOptions
interface that provides the options for thecreateProxyingResolver
property ofSubschemaConfig
options has been adjusted. Theschema
property previously could be set to aGraphQLSchema
or aSubschemaConfig
object. This property has been removed in favor of asubschemaConfig
property that will always be aSubschemaConfig
object. Thetransforms
property has been removed; transforms should be included within theSubschemaConfig
object.` -
The format of the wrapping schema has solidified. All non-root fields are expected to use identical resolvers, either
defaultMergedResolver
or a custom equivalent, with root fields doing the hard work of proxying. Support for custom merged resolvers throughcreateMergedResolver
has been deprecated, as custom merging resolvers conflict when using stitching’s type merging, where resolvers are expected to be identical across subschemas. -
The
WrapFields
transform’swrappingResolver
option has been removed, as this complicates multiple wrapping layers, as well as planned functionality to wrap subscription root fields in potentially multiple layers, as the wrapping resolvers may be different in different layers. Modifying resolvers can still be performed by use of an additional transform such asTransformRootFields
orTransformObjectFields
. -
The
ExtendSchema
transform has been removed, as it is conceptually simpler just to usestitchSchemas
with one subschema. -
The
ReplaceFieldsWithFragment
,AddFragmentsByField
,AddSelectionSetsByField
, andAddMergedTypeSelectionSets
transforms has been removed, as they are superseded by theAddSelectionSets
andVisitSelectionSets
transforms. TheAddSelectionSets
purposely takes parsed SDL rather than strings, to nudge end users to parse these strings at build time (when possible), rather than at runtime. Parsing of selection set strings can be performed using theparseSelectionSet
function from@graphql-tools/utils
.
Schema Stitching (stitchSchemas
& @graphql-tools/stitch
)
-
stitchSchemas
’smergeTypes
option is now true by default! This causes theonTypeConflict
option to be ignored by default. To useonTypeConflict
to select a specific type instead of simply merging, simply setmergeTypes
to false. -
schemas
argument has been deprecated, usesubschemas
,typeDefs
, ortypes
, depending on what you are stitching. -
When using batch delegation in type merging, the
argsFromKeys
function is now set only via theargsFromKeys
property. Previously, ifargsFromKeys
was absent, it could be read fromargs
. -
Support for fragment hints has been removed in favor of selection set hints. To migrate you need to replace your resolver fragment hints for selection set hints eg.:
Type: {
fragment: '... on Type { id }'
resolve: () => { ... }
}
for
Type: {
selectionSet: '{ id }'
resolve: () => { ... }
}
stitchSchemas
now processes allGraphQLSchema
andSubschemaConfig
subschema input into newSubschema
objects, handling schema config directives such aso@computed
as well as generating the final transformed schema, stored as thetransformedSchema
property, if transforms are used. Signatures of theonTypeConflict
,fieldConfigMerger
, andinputFieldConfigMerger
have been updated to include metadata related to the original and transformed subschemas. Note the property name change foronTypeConflict
fromschema
tosubschema
.
Mocking (addMocksToSchema
and @graphql-tools/mock
)
- Mocks returning objects with fields set as functions are now operating according to the upstream
graphql-js
convention, i.e. these functions take three arguments,args
,context
, andinfo
withparent
available asthis
rather than as the first argument.
Other Utilities (@graphql-tools/utils
)
filterSchema
’sfieldFilter
will now filter all fields across Object, Interface, and Input types. For the previous Object-only behavior, switch to theobjectFieldFilter
option.- Unused
fieldNodes
utility functions have been removed. - Unused
typeContainsSelectionSet
function has been removed, andtypesContainSelectionSet
has been moved to thestitch
package. - Unnecessary
Operation
type has been removed in favor ofOperationTypeNode
from upstream graphql-js. - As above,
applySchemaTransforms
/applyRequestTransforms
/applyResultTransforms
have been removed from theutils
package, as they are implemented elsewhere or no longer necessary.
Upgrading from v4/v5
If you are using GraphQL Tools v4/v5, additional changes are necessary.
Monorepo Design
You can still import functions directly from graphql-tools
, but we encourage you to instead import functions from specific packages under the new mono repo design: @graphql-tools/schema
, @graphql-tools/merge
, etc.
Schema Generation and Decoration API (@graphql-tools/schema
)
The majority of schema modification functions now return new, altered schemas rather than modifying the original schema in place. Note that several functions have been renamed as ResolveFunctions
and MockFunctions
have been shortened to Resolvers
and Mocks
throughout the code base and documentation:
makeExecutableSchema
addResolveFunctionsToSchema
=>addResolversToSchema
attachDirectiveResolvers
addSchemaLevelResolveFunctions
=>addSchemaLevelResolver
addCatchUndefinedToSchema
addErrorLoggingToSchema
addMockFunctionsToSchema
=>addMocksToSchema
Schema modification functions operating on fields now similarly take a schema as a parameter and return a new schema, rather than modifying the passed in typeMap
(and requiring manual schema healing).
appendObjectFields
removeObjectFields
The addConnectorsToContext
has been deprecated in favor of manually attaching connectors to context, see #140.
Abstract types that use resolveType
properties to return an actual type rather than a type name may be unstable when using graphql-tools
, as these types are hidden from the type map and cannot be recreated. These resolveType
resolvers should be relatively easy to rewrite to use the name of a known GraphQLObject
type included within the schema’s type map. This will soon be the recommended approach in upstream graphql-js
as well, see #2279.
Remote Schemas & Wrapping (wrapSchema
, makeRemoteExecutableSchema
, and @graphql-tools/wrap
)
-
Remote schema wrapping is now accomplished by using executors and subscribers rather than fetchers and links. Functions that convert links to executors/subscribers are included with @graphql-tools/links. See the docs.
-
Transform
<*>Field Transforms
now all take afieldTransformer
with alteredFieldTransformer
type. A FieldTransformer receives a field config as an argument rather than a field, so that library users are spared having to call fieldToFieldConfig. AFieldTransformer
can return an array of type[string, GraphQLFieldConfig<any, any>]
instead of an object{ name: string, field: GraphQLFieldConfig<any, any> }
if it wishes to rename the field, the tuple is less verbose — and the object is misnamed, it should be{ newName, newFieldConfig }
.
Schema Stitching (stitchSchemas
& @graphql-tools/stitch
)
- Stitching has been renamed (
mergeSchemas
=>stitchSchemas
) resolvers
parameter passed tostitchSchemas
match type signature of resolvers passed to makeExecutableSchema (and can no longer be functions). Stitching metadata stored within “mergeInfo” may still be accessed within each resolver underinfo.schema.extensions.stitchingInfo
.- Custom proxying resolvers take an options object instead of individual parameters, a breaking change from v5, when the custom proxying resolvers were introduced.
Schema Delegation (delegateToSchema
& @graphql-tools/delegate
)
- As above,
mergeInfo
inGraphQLResolveInfo
has been replaced bystitchingInfo
inGraphQLSchema
s extensions. delegateToSchema
is not available inmergeInfo
orstitchingInfo
anymore. Simply import thedelegateToSchema
function from thedelegate
package instead.
Other Utilities (@graphql-tools/utils
)
- Polyfills for GraphQL versions earlier than 14.2 have been removed, including
toConfig
fieldToFieldConfig
andinputFieldToInputFieldConfig
functionality is now exported separately, although library users should ideally not have to use them.