Skip to content
This repository has been archived by the owner on Apr 15, 2020. It is now read-only.

Commit

Permalink
docs(delegateToSchema): update use cases and defaultMergedResolver usage
Browse files Browse the repository at this point in the history
  • Loading branch information
yaacovCR committed Sep 25, 2019
1 parent 1c38f8f commit abac1f1
Showing 1 changed file with 10 additions and 13 deletions.
23 changes: 10 additions & 13 deletions docs/source/schema-delegation.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@ title: Schema delegation
description: Forward queries to other schemas automatically
---

Schema delegation is a way to automatically forward a query (or a part of a query) from a parent schema to another schema (called a _subschema_) that is able to execute the query. Delegation is useful when the parent schema shares a significant part of its data model with the subschema. For example, the parent schema might be powering a GraphQL gateway that connects multiple existing endpoints together, each with its own schema. This kind of architecture could be implemented using schema delegation.
Schema delegation is a way to automatically forward a query (or a part of a query) from a parent schema to another schema (called a _subschema_) that is able to execute the query. Delegation is useful when the parent schema shares a significant part of its data model with the subschema. For example:

* A GraphQL gateway that connects multiple existing endpoints together, each with its own schema, could be implemented as a parent schema that delegates portions of queries to the relevant subschemas.
* Any local schema can directly wrap remote schemas and optionally extend them with additional fields. As long as schema delegation is unidirectional, no gateway is necessary. Simple examples are schemas that wrap other autogenerated schemas (e.g. Postgraphile, Hasura, Prisma) to add custom functionality.

Delegation is performed by one function, `delegateToSchema`, called from within a resolver function of the parent schema. The `delegateToSchema` function sends the query subtree received by the parent resolver to the subschema that knows how to execute it. Fields for the merged types use the `defaultMergedResolver` resolver to extract the correct data from the query response.

The `graphql-tools` package provides several related tools for managing schema delegation:

* [Remote schemas](/remote-schemas/) - turning a remote GraphQL endpoint into a local schema
* [Schema transforms](/schema-transforms/) - modifying existing schemas to make delegation easier
* [Schema stitching](/schema-stitching/) - merging multiple schemas into one

Delegation is performed by one function, `delegateToSchema`, called from within a resolver function of the parent schema. The `delegateToSchema` function sends the query subtree received by the parent resolver to a subschema that knows how to execute it, then returns the result as if the parent resolver had executed the query.

## Motivational example

Let's consider two schemas, a subschema and a parent schema that reuses parts of a subschema. While the parent schema reuses the *definitions* of the subschema, we want to keep the implementations separate, so that the subschema can be tested independently, or even used as a remote service.
Expand Down Expand Up @@ -102,11 +105,13 @@ query($id: ID!) {

Delegation also removes the fields that don't exist on the subschema, such as `user`. This field would be retrieved from the parent schema using normal GraphQL resolvers.

Each field on the `Repository` and `Issue` types should use the `defaultMergedResolver` to properly extract data from the delegated response. Although in the simplest case, the default resolver can be used for the merged types, `defaultMergedResolver` resolves aliases, converts custom scalars and enums to their internal representations, and maps errors.

## API

### delegateToSchema

The `delegateToSchema` method can be found on the `info.mergeInfo` object within any resolver function, and should be called with the following named options:
The `delegateToSchema` method should be called with the following named options:

```
delegateToSchema(options: {
Expand Down Expand Up @@ -190,14 +195,6 @@ GraphQL context that is going to be past to subschema execution or subsciption c

GraphQL resolve info of the current resolver. Provides access to the subquery that starts at the current resolver.

Also provides the `info.mergeInfo.delegateToSchema` function discussed above.

#### transforms: Array<Transform>

[Transforms](/schema-transforms/) to apply to the query and results. Should be the same transforms that were used to transform the schema, if any. After transformation, `transformedSchema.transforms` contains the transforms that were applied.

## Additional considerations

### Aliases

Delegation preserves aliases that are passed from the parent query. However that presents problems, because default GraphQL resolvers retrieve field from parent based on their name, not aliases. This way results with aliases will be missing from the delegated result. `mergeSchemas` and `transformSchemas` go around that by using `src/stitching/defaultMergedResolver` for all fields without explicit resolver. When building new libraries around delegation, one should consider how the aliases will be handled.
[Transforms](/schema-transforms/) to apply to the query and results. Should be the same transforms that were used to transform the schema, if any. For convenience, after transformation, `transformedSchema.transforms` contains the transforms that were applied.

0 comments on commit abac1f1

Please sign in to comment.