Operational
It may be sometimes useful to add additional transforms to manually change an operation request or
result when using delegateToSchema
. Common use cases may be moving selections around or to wrap
them. The following built-in transforms may be useful in those cases.
WrapFields('ParentType', ['scope'], ['ScopeType'], ['field1', 'field2', ...])
wraps a collection of fields on a parent type in one or more wrapping scopes with given namespaces and object types.ExtractField({ from: Array<string>, to: Array<string> })
move selection atfrom
path toto
path.WrapQuery(path: Array<string>, wrapper: QueryWrapper, extractor: (result: any) => any)
wrap a selection atpath
using functionwrapper
. Applyextractor
at the same path to get the result. This is used to get a result nested inside another result.
import { WrapQuery } from '@graphql-tools/wrap'
const schema = wrapSchema({
// ...
transforms: [
// Wrap document takes a subtree as an AST node
new WrapQuery(
// path at which to apply wrapping and extracting
['userById'],
(subtree: SelectionSetNode) => ({
// we create a wrapping AST Field
kind: Kind.FIELD,
name: {
kind: Kind.NAME,
// that field is `address`
value: 'address'
},
// Inside the field selection
selectionSet: subtree
}),
// how to process the data result at path
result => result?.address
)
]
})
WrapQuery
can also be used to expand multiple top-level query fields
import { SelectionSetNode } from 'graphql'
import { WrapQuery } from '@graphql-tools/wrap'
const schema = wrapSchema({
// ...
transforms: [
// Wrap document takes a subtree as an AST node
new WrapQuery(
// path at which to apply wrapping and extracting
['userById'],
(subtree: SelectionSetNode) => {
const newSelectionSet = {
kind: Kind.SELECTION_SET,
selections: subtree.selections.map(selection => {
// just append fragments, not interesting for this
// test
if (
selection.kind === Kind.INLINE_FRAGMENT ||
selection.kind === Kind.FRAGMENT_SPREAD
) {
return selection
}
// prepend `address` to name and camelCase
const oldFieldName = selection.name.value
return {
kind: Kind.FIELD,
name: {
kind: Kind.NAME,
value: 'address' + oldFieldName.charAt(0).toUpperCase() + oldFieldName.slice(1)
}
}
})
}
return newSelectionSet
},
// how to process the data result at path
result => ({
streetAddress: result.addressStreetAddress,
zip: result.addressZip
})
)
]
})