New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore(blog): add schema customization blog post release #12522
Merged
freiksenet
merged 12 commits into
gatsbyjs:schema-refactor-new
from
DSchau:blog/releasing-schema-customization
Mar 18, 2019
Merged
Changes from 10 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
79b195d
chore(blog): add schema customization blog post release
DSchau 74df165
chore: tweak first sentence
DSchau 48967db
Update docs/blog/2019-03-18-releasing-new-schema-customization/index.md
marcysutton d2f84c5
Update docs/blog/2019-03-18-releasing-new-schema-customization/index.md
marcysutton e6c89de
Update docs/blog/2019-03-18-releasing-new-schema-customization/index.md
marcysutton 7c5f6ec
Update docs/blog/2019-03-18-releasing-new-schema-customization/index.md
marcysutton 2209d7c
Update docs/blog/2019-03-18-releasing-new-schema-customization/index.md
marcysutton a6d6b29
Update docs/blog/2019-03-18-releasing-new-schema-customization/index.md
marcysutton eec7b6e
chore: address feedback
DSchau 051bb71
Merge branch 'blog/releasing-schema-customization' of github.com:DSch…
DSchau 67bea92
Update docs/blog/2019-03-18-releasing-new-schema-customization/index.md
DSchau c0897e5
Merge branch 'schema-refactor-new' into blog/releasing-schema-customi…
freiksenet File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
131 changes: 131 additions & 0 deletions
131
docs/blog/2019-03-18-releasing-new-schema-customization/index.md
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,131 @@ | ||
--- | ||
title: New Schema Customization API - Available in Gatsby 2.2.0 | ||
date: 2019-03-18 | ||
author: Mikhail Novikov | ||
tags: | ||
- schema | ||
- graphql | ||
--- | ||
|
||
Two weeks ago, we announced our plans for a [new schema customization API](/blog/2019-03-04-new-schema-customization/). Today we are making this set of new APIs and enhancements available to all in `gatsby`@`2.2.0`. | ||
|
||
First, install the latest and greatest version of `gatsby`, like so: | ||
|
||
```shell | ||
npm install gatsby --save | ||
``` | ||
|
||
Next, continue reading below to see if any of the great, new features we've enabled scratch a particular itch. We feel very confident you're going to love these new features 💜 | ||
|
||
# Recap of schema customization | ||
|
||
Before this change, the Gatsby GraphQL schema was generated automatically from the data that the user added to Gatsby. While very convenient and easy to start, changes to the data could cause changes to the schema, which could cause breakage in unrelated locations. Those bugs were confusing and hard to debug. To alleviate this problem, we've added a schema customization API that lets you customize, fix, and enhance types in your Gatsby GraphQL schema. | ||
|
||
There are two new APIs, `createTypes` and `createResolvers`. | ||
|
||
## `createTypes` | ||
|
||
`createTypes` can be used to define, fix, or extend a Node's GraphQL type representation. Think of it like an escape hatch to politely inform Gatsby of your data's shape and give the automatically inferred shape super powers. | ||
DSchau marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```js:title=gatsby-node.js | ||
exports.sourceNodes = ({ actions }) => { | ||
const { createTypes } = actions | ||
const typeDefs = ` | ||
type AuthorJson implements Node { | ||
name: String | ||
birthday: Date | ||
} | ||
` | ||
createTypes(typeDefs) | ||
} | ||
``` | ||
|
||
After adding this to your [gatsby-node](/docs/gatsby-project-structure/#files) file, the `AuthorJson` type will always have fields name and birthday, regardless of the automatically inferred data shape. The rest of the fields will still be inferred normally, allowing you to enjoy the default benefits of Gatsby schema inference. | ||
|
||
## `createResolvers` | ||
|
||
`createResolvers` allows doing additional customization after all schema processing has been finished. Thus it can be used to add fields to any types, including root types like `Query` and types from third party schemas. | ||
|
||
```js:title=gatsby-node.js | ||
createResolvers({ | ||
Query: { | ||
allAuthorFullNames: { | ||
type: `[String!]!`, | ||
resolve(source, args, context, info) { | ||
const authors = context.nodeModel.getAllNodes({ | ||
type: `AuthorJson`, | ||
}) | ||
return authors.map(author => author.name) | ||
}, | ||
}, | ||
}, | ||
}) | ||
``` | ||
|
||
## The Type Builder API | ||
|
||
While `createTypes` accepts `graphql-js` types along with a [Schema Definition Language (SDL)](https://www.prisma.io/blog/graphql-sdl-schema-definition-language-6755bcb9ce51) string, we've also added an option to use `graphql-js` types so that users could create types with resolvers. However, `graphql-js` is somewhat verbose and it can be hard to refer to types that don't yet exist or don't exist in a current scope. Therefore, we decided to add another programmatic AP that combines brevity of SDL with flexibility of `graphql-js`. | ||
|
||
We refer to this API as the _Type Builder API_. It is available in the `schema` field of the arguments object passed to [Gatsby Node APIs](/docs/node-apis/). | ||
|
||
```js:title=gatsby-node.js | ||
exports.sourceNodes = ({ actions, schema }) => { | ||
const { createTypes } = actions | ||
createTypes([ | ||
schema.buildObjectType({ | ||
name: `CommentJson`, | ||
fields: { | ||
text: `String!`, | ||
blog: { | ||
type: `BlogJson`, | ||
resolve(parent, args, context) { | ||
return context.nodeModel.getNodeById({ | ||
id: parent.author, | ||
type: `BlogJson`, | ||
}) | ||
}, | ||
}, | ||
author: { | ||
type: `AuthorJson`, | ||
resolve(parent, args, context) { | ||
return context.nodeModel.getNodeById({ | ||
id: parent.author, | ||
type: `AuthorJson`, | ||
}) | ||
}, | ||
}, | ||
}, | ||
interfaces: [`Node`], | ||
}), | ||
]) | ||
} | ||
``` | ||
|
||
# Potential for Breaking Changes | ||
|
||
We have tried to avoid any breaking changes in this refactor of the underlying GraphQL layer, testing it in notable Gatsby sites and ensuring all tests were passing. However, there are areas where we needed to introduce more stable naming, and in these instances it _could_ be possible that a breaking change was introduced if you were relying on this undocumented API. | ||
|
||
Specifically, before this refactor Gatsby type names weren't stable. They could have names like `frontmatter_2` because of some quirks in our schema generation. Now the types names are **stable** and **defined**. For a `Node`, it's always a Pascal Camel Cased name of the `Node` type (for example, `AllMarkdownRemark`). For an inline object, it's the name of the node plus the name of the field, again Pascal Camel Cased. So `frontmatter_2` would be available as `MarkdownRemarkFrontmatter` now. If you've had fragments referring to some types by their old names, you may need to change it to new names, e.g.: | ||
|
||
```diff | ||
- fragment someFragment on frontmatter_2 { | ||
+ fragment someFragment on MarkdownRemarkFrontmatter { | ||
title | ||
} | ||
``` | ||
|
||
Another change relates to inference. Previously, ordering of the Nodes in your data source could affect which type Gatsby inferred. Now, we always consider all possible types, thus you might experience type conflicts for conflicting data sources. They can be solved by either fixing the data or defining a type using new schema customization APIs that we've exposed. | ||
|
||
# Wrap-up | ||
|
||
As next steps, we will work on adding more convenient tooling to "freeze" your schema type definitions, so that you can quickly start using this feature. We will also be working on improving API docs for this. | ||
|
||
We strongly believe that these new APIs are the foundation of an evolutionary leap of the Gatsby GraphQL API. These changes make the GraphQL API more stable, more robust, and more easily customizable. They will enable further customization and use cases, like [theming][/blog/2018-11-11-introducing-gatsby-themes/] and more still that we haven't even envisioned yet. We truly can't wait to see the great things you build and how you use these new APIs and improvements powered by Gatsby and its improved GraphQL layer. | ||
|
||
## Additional Resources | ||
|
||
- [Meta issue](https://github.com/gatsbyjs/gatsby/issues/12272) for bug reports | ||
- [API docs for createTypes](/docs/actions/#createTypes) | ||
- [API docs for createResolvers](/docs/node-apis/#createResolvers) | ||
- [API docs for node model](/docs/node-model) | ||
- [Using type definitions example](https://github.com/gatsbyjs/gatsby/tree/master/examples/using-type-definitions) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Maybe:
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.
(Very open to tweaks here :))