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

Commit

Permalink
fix(docs): expands transforms docs
Browse files Browse the repository at this point in the history
  • Loading branch information
yaacovCR committed Oct 13, 2019
1 parent ec00d65 commit bcd55f6
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 14 deletions.
2 changes: 1 addition & 1 deletion docs/source/schema-delegation.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,4 +197,4 @@ GraphQL resolve info of the current resolver. Provides access to the subquery th

#### 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. For convenience, after transformation, `transformedSchema.transforms` contains the transforms that were applied.
Any additional operation [transforms](/schema-transforms/) to apply to the query and results. Could be the same operation transforms used in conjunction with schema transformation. For convenience, after schema transformation, `transformedSchema.transforms` contains the transforms that were applied.
29 changes: 16 additions & 13 deletions docs/source/schema-transforms.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ title: Schema transforms
description: Automatically transforming schemas
---

Schema transforms are a tool for making modified copies of `GraphQLSchema` objects, while preserving the possibility of delegating back to original schema.
Schema transforms are a tool for making modified copies of `GraphQLSchema` objects, without changing the original schema implementation. This is especially useful when the original schema _cannot_ be changed, i.e. when using [remote schemas](/remote-schemas/).

Transforms are useful when working with [remote schemas](/remote-schemas/), building GraphQL gateways that combine multiple schemas, and/or using [schema stitching](/schema-stitching/) to combine schemas together without conflicts between types or fields.
Schema transforms can be useful when building GraphQL gateways that combine multiple schemas and/or using [schema stitching](/schema-stitching/) to combine schemas together without conflicts between types or fields.

While it's possible to modify a schema by hand, the manual approach requires a deep understanding of all the relationships between `GraphQLSchema` properties, which makes it error-prone and labor-intensive. Transforms provide a generic abstraction over all those details, which improves code quality and saves time, not only now but also in the future, because transforms are designed to be reused again and again.

Each `Transform` may define three different kinds of transform functions:
Schema transforms work by wrapping the original schema in a new outer schema that simply delegates all operations to the original inner schema. Each schema transform includes a function that changes the outer wrapping schema. It may also include an operation transform, i.e. functions that either modify the operation prior to delegation or modify the result prior to its return.

```ts
interface Transform = {
Expand All @@ -19,8 +17,6 @@ interface Transform = {
};
```

The most commonly used transform function is `transformSchema`. However, some transforms require modifying incoming requests and/or outgoing results as well, especially if `transformSchema` adds or removes types or fields, since such changes require mapping new types/fields to the original types/fields at runtime.

For example, let's consider changing the name of the type in a simple schema. Imagine we've written a function that takes a `GraphQLSchema` and replaces all instances of type `Test` with `NewTest`.

```graphql
Expand All @@ -46,7 +42,7 @@ type Query {
}
```

At runtime, we want the `NewTest` type to be automatically mapped to the old `Test` type.
On delegation to the inner, original schema, we want the `NewTest` type to be automatically mapped to the old `Test` type.

At first glance, it might seem as though most queries work the same way as before:

Expand Down Expand Up @@ -102,11 +98,15 @@ type Result = ExecutionResult & {
};
```

### transformSchema
### wrapSchema / transformSchema

Given a `GraphQLSchema` and an array of `Transform` objects, produce a new schema with those transforms applied.

Delegating resolvers will also be generated to map from new schema root fields to old schema root fields. Often these automatic resolvers are sufficient, so you don't have to implement your own.
Delegating resolvers are generated to map from new schema root fields to old schema root fields. These automatic resolvers should be sufficient, so you don't have to implement your own.

The delegating resolvers will apply the operation transforms defined by the `Transform` objects. Each provided `transformRequest` functions will be applies in reverse order, until the request matches the original schema. The `tranformResult` functions will be applied in the opposite order until the result matches the outer schema.

For convenience, when using `transformSchema`, after schema transformation, the `transforms` property on a returned `transformedSchema` object will contains the operation transforms that were applied. This could be useful when manually delegating to the original schema from an outer schema.

## Built-in transforms

Expand Down Expand Up @@ -218,7 +218,9 @@ RenameObjectFields(
)
```

### Other
### Additional Operation Transforms

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 move selections around or to wrap them. The following built-in transforms may be useful in those cases.

* `ExtractField({ from: Array<string>, to: Array<string> })` - move selection at `from` path to `to` path.

Expand Down Expand Up @@ -298,8 +300,9 @@ transforms: [
The following transforms are automatically applied by `delegateToSchema` during schema delegation, to translate between new and old types and fields:
* `AddArgumentsAsVariables`: Given a schema and arguments passed to a root field, make those arguments document variables.
* `ExpandAbstractTypes`: If an abstract type within a document does not exist in the inner schema, expand the type to each and any of its implementations that do exist in the inner schema.
* `FilterToSchema`: Given a schema and document, remove all fields, variables and fragments for types that don't exist in that schema.
* `AddTypenameToAbstract`: Add `__typename` to all abstract types in the document.
* `AddTypenameToAbstract`: Add `__typename` to all abstract types in the document, necessary for type resolution of interfaces within the outer schema to work.
* `CheckResultAndHandleErrors`: Given a result from a subschema, propagate errors so that they match the correct subfield. Also provide the correct key if aliases are used.
By passing a custom `transforms` array to `delegateToSchema`, it's possible to run additional transforms before these default transforms, though it is currently not possible to disable the default transforms.
By passing a custom `transforms` array to `delegateToSchema`, it's possible to run additional operation (request/result) transforms before these default transforms.

0 comments on commit bcd55f6

Please sign in to comment.