Extending the Unified Schema
We saw on the "How to: Combine multiple Sources"
guide that additionalResolvers
could be used to shape and augment the Unified Schema with custom
resolvers.
However, the additionalResolvers
value can also be the path to a JavaScript/TypeScript file that
exports the custom resolvers implementation.
Programmatic additionalResolvers
In our "How to: Combine multiple Sources" Gateway,
the additionalResolvers
could have been provided programmatically as shown in the
multiple-sources-prog-resolvers
example.
The below .meshrc.yaml
configuration add the following fields:
Store.bookSells: [Sells!]!
: to get the selling from a given storeSells.book: Book
: to get the book of a given store selling recordBook.author: authors_v1_Author
: to get the author of a book
sources:
# …
transforms:
# …
additionalTypeDefs: |
extend type Store {
bookSells: [Sells!]!
}
extend type Sells {
book: Book
}
extend type Book {
author: authors_v1_Author
}
additionalResolvers:
- './resolvers'
import { Resolvers } from './.mesh'
const resolvers: Resolvers = {
Book: {
author: {
selectionSet: /* GraphQL */ `
{
authorId
}
`,
resolve(root, _args, context, info) {
return context.Authors.Query.authors_v1_AuthorsService_GetAuthor({
root,
args: {
input: {
id: root.authorId
}
},
context,
info
})
}
}
},
Store: {
bookSells: {
selectionSet: /* GraphQL */ `
{
id
}
`,
resolve(root, _args, context, info) {
return context.Stores.Query.bookSells({
root,
args: {
storeId: root.id
},
context,
info
})
}
}
},
Sells: {
book: {
selectionSet: /* GraphQL */ `
{
bookId
}
`,
resolve(root, _args, context, info) {
return context.Books.Query.book({
root,
args: {
id: root.bookId
},
context,
info
})
}
}
}
}
export default resolvers
Mesh relies on GraphQL Code Generator to generate the
Resolvers
type that gives you access to:
- fully typed resolvers map
- fully typed SDK (through the
context
) to fetch data from Sources
Using the SDK to fetch Sources
Let's take a closer look at the Book.author
resolver implementation.
The resolver is accessing the "Authors" source SDK through the context
to fetch data from the
authors_v1_AuthorsService_GetAuthor(id: ID!)
Query as follows:
await context.Authors.Query.authors_v1_AuthorsService_GetAuthor({
root,
args: {
input: {
id: root.authorId
}
},
context,
info
})
authors_v1_AuthorsService_GetAuthor
is a generated SDK method that allows to query our gRPC Books
Source as it was a GraphQL Schema.
Any SDK method take the following arguments:
root
,context
andinfo
are mandatory parameters that we forward from the resolvers calling the method. If the current field's return type doesn't match, you should provide aselectionSet
.args
: arguments to pass to the Mutation or QueryselectionSet
: allows to specify a selection on the Query/Mutation to fetch nested data like{ id name }
valuesFromResults
: allows to provide a function to transform the results (if the result is an array, the function will be mapped to each element)
Note: valuesFromResults
, compared to selectionSet
helps to "flatten"/"un-nest" data from
results
Going further
Transforms like "Hoist Field" also helps in shaping and extending the Unified Schema.