From 2111a1cfd810f2c7b2a87377bf0250759f78bc26 Mon Sep 17 00:00:00 2001 From: Mikhail Novikov Date: Mon, 9 Jul 2018 12:10:49 +0300 Subject: [PATCH 1/4] Add native graphql source RFC --- text/0000-native-graphql-source.md | 155 +++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 text/0000-native-graphql-source.md diff --git a/text/0000-native-graphql-source.md b/text/0000-native-graphql-source.md new file mode 100644 index 0000000000000..3b2e7b3dffade --- /dev/null +++ b/text/0000-native-graphql-source.md @@ -0,0 +1,155 @@ +- Start Date: 2018-07-09 +- RFC PR: (leave this empty) +- Gatsby Issue: (leave this empty) + +# Summary + +This RFCs proposes the way to add third-party GraphQL schemas into Gatsby core schema. In addition to a low-level API to add schemas to be stitched, it describes a higher-level API/plugin to integrate third-party APIs into your Gatbsy API. + +[Implementation](https://github.com/gatsbyjs/gatsby/tree/graphql/schema-stitching) + +# Basic example + +Plugin API: + +```js +// In your gatsby-config.js +module.exports = { + plugins: [ + // Simple config, passing URL + { + resolve: "gatsby-source-graphql", + options: { + // This type will contain remote schema Query type + typeName: "SWAPI", + // This is field under which it's accessible + fieldName: "swapi", + // Url to query from + url: "https://api.graphcms.com/simple/v1/swapi", + }, + }, + // Passing paramaters (passed to apollo-link) + { + resolve: "gatsby-source-graphql", + options: { + typeName: "GitHub", + fieldName: "github", + // Url to query from + url: "https://api.github.com/graphql", + // HTTP headers + headers: { + Authorization: "bearer ", + }, + // Additional options to pass to node-fetch + fetchOptions: {}, + }, + }, + // Creating arbitrary Apollo Link (for advanced situations) + { + resolve: "gatsby-source-graphql", + options: { + typeName: "GitHub", + fieldName: "github", + // Create Apollo Link manually. Can return a Promise. + createLink: (pluginOptions) => { + return createHttpLink({ + uri: 'https://api.github.com/graphql', + headers: { + 'Authorization': `bearer ${process.env.GITHUB_TOKEN}`, + }, + fetch, + }) + }, + }, + ], +} +``` + +Querying it + +```graphql +{ + # Field name parameter defines how you can access third party api + swapi { + allSpecies { + name + } + } + github { + viewer { + email + } + } +} +``` + +Low-level Gatsby API for future plugins + +```js +exports.sourceNodes = async ({ boundActionCreators }) => { + const { addThirdPartySchema } = boundActionCreators + addThirdPartySchema(yourGraphQLJSExecutableSchema) +}) +``` + +# Motivation + +When Gatsby started, there weren't that many GraphQL APIs in the wild. Nowadays, not only there are many public GraphQL APIs, but also many people have their own internal GraphQL API. Tools like Prisma and AWS Appsync are increasingly popular. As Gastby uses GraphQL, it's weird that there is no native way to use those plugin schemas. Currently one needs to create a custom source plugin for every GraphQL API. + +This RFCs proposes the way to automatically merge Gatsby schema with third-party APIs. In addition, it provides a simple to use plugin to do that, that should cover most of the use cases. + +Low-level API should also enable a more deep customization of Gatsby Schemas, by exposing almost full power of graphql-tools schema-stitching. This probably will allow more advanced tools that replace or modify some built-in types. + +# Detailed design + +## Action Creator + +`addThirdPartySchema(schema: GraphQLSchema)` + +Adds a schema to third-party schema list. At schema creation time all the schemas are merged with [schema stitching](https://www.apollographql.com/docs/graphql-tools/schema-stitching.html) + +## graphql-source-graphql + +This is a higher level plugin. Instead of just merging a schema, it allows a more simple way of merging an third-party GraphQL API into the Gatsby schema. It also handles namespacing, both on type and field level. Features: + +* Merge in a GraphQL Schema from an API. Schema can be automatically introspected or provided through a callback. +* In case of introspection, schema is cached. +* Connection parameters can provided both in simplified form (`url` and `params`) or by providing a callback that creates `apollo-link` +* Namespace all types in the schema +* Put schema's Query type under a specified `fieldName` as an object type with a `typeName`. This means the third-party schema won't be pollute the main Gatsby namespace or conflict with it. + +### Options + +* `typeName: string` (required) - type to put third-party schema's Query type into +* `fieldName: string` (required) - field into which Gatsby's third-party API will be added +* `url: string?` - url of a third-party service +* `headers: object?` - headers to add to the request +* `fetchOptions: object?` - additional `node-fetch` options +* `createLink: (options: object) => ApolloLink` - a callback that will create an ApolloLink instance that should query the third-party API. An escape hatch that overrides `url`, `headers` and `fetchOptions` parameters above and allows complex logic for eg authorization +* `createSchema: (options: object) => GraphQLSchema` - callback that will create a GraphQLSchema of a third-party API. Resolvers are going to be ignored. This allows not using introspection (eg if it's disabled) or to customize third-party schema before passing it to stitching + +Either `url` or `createLink` must be specified. If no `createSchema` is passed, third-party schema must support introspection. + +# Drawbacks + +Schema stitching takes additional time, so schema creation time will increase. + +# Alternatives + +Keep writing custom plugins for each GraphQL API. + +Alternatively, one can write a plugin that converts a third-party GraphQL schema into Gatsby nodes. My evaluation is that it's going to be more complex at the end. + +One could consider a more higher-level API for adding third-party schemas, instead of a current very low-level one. However, as we don't yet know all the possible use cases with this, I'd err on being too low level. + +# Adoption strategy + +This plugin doesn't remove or change APIs, only adds new ones. Should be backwards compatible. Possibly, existing GraphQL plugins should eventually be deprecated in favor of using this one directly. + +# How we teach this + +This adds one function to plugin API and one new source plugin. This source plugin should be introduced to people who use GraphQL in the documentation. There also should be a blog post and some tutorial projects using this. + +# Unresolved questions + +Integration with Gatsby incremental builds. Current ideas is incremental approach - first the whole third-party API will be considered one Node, then we'll add callbacks to allow creating nodes from third-party APIs. From 3233a3990d7bc5e3696942592689b8975c68463c Mon Sep 17 00:00:00 2001 From: Mikhail Novikov Date: Mon, 9 Jul 2018 14:27:03 +0300 Subject: [PATCH 2/4] Add simple example --- text/0000-native-graphql-source.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/text/0000-native-graphql-source.md b/text/0000-native-graphql-source.md index 3b2e7b3dffade..6f4a21c84bad3 100644 --- a/text/0000-native-graphql-source.md +++ b/text/0000-native-graphql-source.md @@ -6,7 +6,8 @@ This RFCs proposes the way to add third-party GraphQL schemas into Gatsby core schema. In addition to a low-level API to add schemas to be stitched, it describes a higher-level API/plugin to integrate third-party APIs into your Gatbsy API. -[Implementation](https://github.com/gatsbyjs/gatsby/tree/graphql/schema-stitching) +* [Implementation](https://github.com/gatsbyjs/gatsby/tree/graphql/schema-stitching) +* [Simple example project](https://github.com/freiksenet/gatsby-github-displayer) # Basic example From f3e1a87b4e9dc9a586ab00c2f971682f70fae42b Mon Sep 17 00:00:00 2001 From: Mikhail Novikov Date: Thu, 12 Jul 2018 14:48:32 +0300 Subject: [PATCH 3/4] Update 0000-native-graphql-source.md --- text/0000-native-graphql-source.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0000-native-graphql-source.md b/text/0000-native-graphql-source.md index 6f4a21c84bad3..ce5bf0a8fe963 100644 --- a/text/0000-native-graphql-source.md +++ b/text/0000-native-graphql-source.md @@ -109,7 +109,7 @@ Low-level API should also enable a more deep customization of Gatsby Schemas, by Adds a schema to third-party schema list. At schema creation time all the schemas are merged with [schema stitching](https://www.apollographql.com/docs/graphql-tools/schema-stitching.html) -## graphql-source-graphql +## github-source-graphql This is a higher level plugin. Instead of just merging a schema, it allows a more simple way of merging an third-party GraphQL API into the Gatsby schema. It also handles namespacing, both on type and field level. Features: From 3f81222a58d11086778b5a7875424c36e5f97ae2 Mon Sep 17 00:00:00 2001 From: Mikhail Novikov Date: Mon, 16 Jul 2018 14:28:07 +0300 Subject: [PATCH 4/4] Update 0000-native-graphql-source.md Derp derp derp, wrong name again. --- text/0000-native-graphql-source.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0000-native-graphql-source.md b/text/0000-native-graphql-source.md index ce5bf0a8fe963..cecd0ada735fc 100644 --- a/text/0000-native-graphql-source.md +++ b/text/0000-native-graphql-source.md @@ -109,7 +109,7 @@ Low-level API should also enable a more deep customization of Gatsby Schemas, by Adds a schema to third-party schema list. At schema creation time all the schemas are merged with [schema stitching](https://www.apollographql.com/docs/graphql-tools/schema-stitching.html) -## github-source-graphql +## gatsby-source-graphql This is a higher level plugin. Instead of just merging a schema, it allows a more simple way of merging an third-party GraphQL API into the Gatsby schema. It also handles namespacing, both on type and field level. Features: