-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Removes
graphQLSchemaExtension
export in favour of using either `gr…
…aphql.extend` or `@graphql-tool/schema` (#7943)
- Loading branch information
Josh Calder
committed
Sep 29, 2022
1 parent
cacc4e1
commit 494cdef
Showing
33 changed files
with
480 additions
and
399 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@keystone-6/core': major | ||
--- | ||
|
||
Removes the `@graphql-tools/schema` wrapping functions `graphQLSchemaExtension` and `gql`. Developers should import `@graphql-tools/schema` themselves, or use `graphql` (as exported by `@keystone-6/core`). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,131 @@ | ||
--- | ||
title: "Schema Extension" | ||
description: "We've planned this page but not had a chance to write it yet." | ||
title: "GraphQL Schema Extension" | ||
description: "Learn how to extend your GraphQL Schema using extendGraphqlSchema." | ||
--- | ||
|
||
{% coming-soon /%} | ||
Keystone automatically generates a GraphQL schema based on your [Keystone config](../config/config). This schema contains all GraphQL types, queries and mutations based on your lists and ends up as the generated `schema.graphql` file found in the root of your Keystone project. | ||
Generally changing the behavior of Keystone can be performed through [Hooks](../config/hooks), however, there are times when you need an extra GraphQL type or want a custom mutation or query, for these instances, Keystone has the `extendGraphqlSchema` option. | ||
|
||
The `extendGraphqlSchema` option expects a function that takes the GraphQL Schema generated by Keystone and returns a valid GraphQL schema. You can then use this function to add or replace resolvers and types. | ||
|
||
## Using Keystone's graphql.extend | ||
|
||
Keystone exports `graphql` from `@keystone/core`, this uses [@graphql-ts/schema](https://docsmill.dev/npm/@graphql-ts/schema) which can be used in combination with `Context` from `.keystone/types` to extend your GraphQL schema in a type-safe way. | ||
|
||
You can then import this into your Keystone configuration file | ||
|
||
```ts | ||
import { graphql } from '@keystone/core'; | ||
``` | ||
|
||
Then you can use `graphql.extend` to add custom resolvers to your GraphQL Schema. | ||
|
||
The following example adds a custom mutation called `publishPost` to the `base` Keystone Schema. It accepts one argument (`args`) of `id` which cannot be null and has the type of ID (`graphql.nonNull(graphql.ID)`). It updates the Post with the corresponding `id` and sets its `status` to 'published' and `publishDate` to the current time. | ||
It then returns the Post that is updated which has a GraphQL type of `Post` that is passed in from the `base` schema (`base.object('Post')`). | ||
|
||
```ts | ||
import { graphql, config } from '@keystone/core'; | ||
import { Context } from '.keystone/types'; | ||
|
||
export default config({ | ||
{/* ... */}, | ||
extendGraphqlSchema: graphql.extend(base => { | ||
return { | ||
mutation: { | ||
publishPost: graphql.field({ | ||
type: base.object('Post'), | ||
args: { id: graphql.arg({ type: graphql.nonNull(graphql.ID) }) }, | ||
resolve(source, { id }, context:Context) { | ||
return context.db.Post.updateOne({ | ||
where: { id }, | ||
data: { status: 'published', publishDate: new Date().toISOString() }, | ||
}); | ||
}, | ||
}), | ||
}, | ||
}; | ||
}), | ||
}); | ||
``` | ||
|
||
{% hint kind="tip" %} | ||
Note `context.db` is used in the resolver, this ensures the correct Internal object with the correct type is returned to GraphQL. | ||
{% /hint %} | ||
|
||
A full example project using `graphql-ts` can be found in [examples/extend-graphql-schema-graphql-ts](https://github.com/keystonejs/keystone/tree/main/examples/extend-graphql-schema-graphql-ts) on the Keystone GitHub repo. | ||
|
||
## Using Third-Party Tools | ||
|
||
As `extendGraphqlSchema` expects a function that returns a valid GraphQL schema you can also use third-party GraphQL schema tools to help generate or merge schemas. | ||
|
||
### GraphQL-Tools Merge Schemas | ||
|
||
[GraphQL Tools](https://www.graphql-tools.com/) `mergeSchemas` is a third-party package that can help with schema merging and adding custom resolvers and types, and then return an updated GraphQL schema to Keystone. | ||
|
||
Start by installing `@graphql-tools/schema` | ||
|
||
```bash | ||
yarn add @graphql-tools/schema | ||
``` | ||
|
||
Then import into your Keystone configuration | ||
|
||
```ts | ||
import { mergeSchemas } from '@graphql-tools/schema'; | ||
``` | ||
|
||
You can then write custom `resolvers` and `typeDefs` to merge with your Keystone `schema`. For example, to add the same custom mutation as above (`publishPost`), you would add the `typeDefs` for `publishPost` and then the `resolvers.Mutation.publishPost` | ||
which performs the same function as above. | ||
|
||
```ts | ||
export default config({ | ||
{/* ... */}, | ||
extendGraphqlSchema: schema => | ||
mergeSchemas({ | ||
schemas: [schema], | ||
typeDefs: ` | ||
type Mutation { | ||
publishPost(id: ID!): Post | ||
`, | ||
resolvers: { | ||
Mutation: { | ||
publishPost: (root, { id }, context) => { | ||
return context.db.Post.updateOne({ | ||
where: { id }, | ||
data: { status: 'published', publishDate: new Date().toUTCString() }, | ||
}); | ||
}, | ||
}, | ||
}, | ||
}), | ||
}); | ||
``` | ||
|
||
{% if $nextRelease %} | ||
{% hint kind="tip" %} | ||
Note - Before version `3.0.0` of `@keystone-6/core`, `@graphql-tools/schema` was exported from `@keystone/core` as `graphQLSchemaExtension` this was removed in favor of using the tool directly if required | ||
{% /hint %} | ||
{% else /%} | ||
{% hint kind="tip" %} | ||
Note - `@graphql-tools/schema` is currently exported from `@keystone/core` as `graphQLSchemaExtension` this will be removed in the next major version of `@keystone-6/core` in favor of using the tool directly if required | ||
{% /hint %} | ||
{% /if %} | ||
|
||
A full example project using `@graphql-tools/schema` can be found in [examples/extend-graphql-schema-graphql-tools](https://github.com/keystonejs/keystone/tree/main/examples/extend-graphql-schema-graphql-tools) on the Keystone GitHub repo. | ||
|
||
## Related resources | ||
|
||
{% related-content %} | ||
{% well heading="Config API Reference" href="/docs/config/config" %} | ||
The complete reference for the base keystone configuration | ||
{% /well %} | ||
{% well heading="Example Project: Extend GraphQL Schema with graphql-ts" href="https://github.com/keystonejs/keystone/tree/main/examples/extend-graphql-schema-graphql-ts" %} | ||
A full keystone project illustrating how to extend your GraphQL schema using graphql-ts provided by Keystone. | ||
{% /well %} | ||
{% well heading="Example Project: Extend GraphQL Schema with GraphQL-Tools" href="https://github.com/keystonejs/keystone/tree/main/examples/extend-graphql-schema-graphql-tools" %} | ||
A full keystone project illustrating how to extend your GraphQL schema using @graphql-tools/schema. | ||
{% /well %} | ||
{% well heading="Example Project: Extend GraphQL Schema with Nexus" href="https://github.com/keystonejs/keystone/tree/main/examples/extend-graphql-schema-nexus" %} | ||
A full keystone project illustrating how to extend your GraphQL schema using Nexus and @graphql-tools/schema. | ||
{% /well %} | ||
{% /related-content %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,20 @@ | ||
import { graphQLSchemaExtension } from '@keystone-6/core'; | ||
import { graphql } from '@keystone-6/core'; | ||
import addToCart from './addToCart'; | ||
import checkout from './checkout'; | ||
|
||
// make a fake graphql tagged template literal | ||
const graphql = String.raw; | ||
export const extendGraphqlSchema = graphQLSchemaExtension({ | ||
typeDefs: graphql` | ||
type Mutation { | ||
addToCart(productId: ID): CartItem | ||
checkout(token: String!): Order | ||
} | ||
`, | ||
resolvers: { | ||
Mutation: { | ||
addToCart, | ||
checkout, | ||
export const extendGraphqlSchema = graphql.extend(base => { | ||
return { | ||
mutation: { | ||
addToCart: graphql.field({ | ||
type: base.object('CartItem'), | ||
args: { productId: graphql.arg({ type: graphql.ID }) }, | ||
resolve: addToCart, | ||
}), | ||
checkout: graphql.field({ | ||
type: base.object('Order'), | ||
args: { token: graphql.arg({ type: graphql.nonNull(graphql.String) }) }, | ||
resolve: checkout, | ||
}), | ||
}, | ||
}, | ||
}; | ||
}); |
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"name": "@keystone-6/example-extend-graphql-schema-graphql-tools", | ||
"version": "0.0.4", | ||
"private": true, | ||
"repository": "https://github.com/keystonejs/keystone/tree/main/examples/extend-graphql-schema-graphql-tools", | ||
"license": "MIT", | ||
"scripts": { | ||
"build": "keystone build", | ||
"dev": "keystone dev", | ||
"start": "keystone start" | ||
}, | ||
"dependencies": { | ||
"@graphql-tools/schema": "^9.0.0", | ||
"@keystone-6/core": "^2.0.0" | ||
}, | ||
"devDependencies": { | ||
"typescript": "~4.7.4" | ||
} | ||
} |
File renamed without changes.
File renamed without changes.
File renamed without changes.
Oops, something went wrong.
494cdef
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
keystone-next-docs – ./
keystone-next-docs-git-main-thinkmill.vercel.app
keystone-6.vercel.app
keystonejs.com
keystone-next-docs-thinkmill.vercel.app
next.keystonejs.com
www.keystonejs.com
demo.keystonejs.com