{"_id":"@chesteralan/gatsby-source-graphql","name":"@chesteralan/gatsby-source-graphql","dist-tags":{"latest":"4.17.0-graphql-source-name.0"},"versions":{"4.17.0-graphql-source-name.0":{"name":"@chesteralan/gatsby-source-graphql","description":"Gatsby plugin which adds a third-party GraphQL API to Gatsby GraphQL","version":"4.17.0-graphql-source-name.0","author":{"name":"Mikhail Novikov","email":"freiksenet@gmail.com"},"bugs":{"url":"https://github.com/gatsbyjs/gatsby/issues"},"dependencies":{"@apollo/client":"^3.5.10","@babel/runtime":"^7.15.4","@graphql-tools/links":"^8.2.14","@graphql-tools/utils":"^8.6.9","@graphql-tools/wrap":"^8.3.3","dataloader":"^2.0.0","gatsby-core-utils":"^3.17.0-next.0","invariant":"^2.2.4","node-fetch":"^2.6.7"},"devDependencies":{"@babel/cli":"^7.15.4","@babel/core":"^7.15.5","babel-preset-gatsby-package":"^2.17.0-next.0","cross-env":"^7.0.3"},"homepage":"https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-source-graphql#readme","keywords":["gatsby","gatsby-plugin"],"license":"MIT","peerDependencies":{"gatsby":"^4.0.0-next"},"repository":{"type":"git","url":"git+https://github.com/gatsbyjs/gatsby.git","directory":"packages/gatsby-source-graphql"},"scripts":{"build":"babel src --out-dir . --ignore \"**/__tests__\"","prepare":"cross-env NODE_ENV=production npm run build","watch":"babel -w src --out-dir . --ignore \"**/__tests__\""},"engines":{"node":">=14.15.0"},"_id":"@chesteralan/gatsby-source-graphql@4.17.0-graphql-source-name.0","_nodeVersion":"14.18.2","_npmVersion":"8.5.5","dist":{"integrity":"sha512-CUExTTjdOs6pKk8PiCxeLM8x8Re9ACTH46KIJfKFYzFZxWMs7cOtHrwG86YMLbbRywAdT15CUtM/Unv6SWYCQA==","shasum":"d2361a15dc9d7ddd95c30c5f2b17e1c6bf8c8acd","tarball":"https://registry.npmjs.org/@chesteralan/gatsby-source-graphql/-/gatsby-source-graphql-4.17.0-graphql-source-name.0.tgz","fileCount":10,"unpackedSize":72867,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHiKTJrCzMd0HSUy87NXDiw+XNucVu1gtMYt/Jcn0kzIAiEA/BKEeVx2W39DEAbiGeG6SoKJzTUNq6ihFVNIkhsIf9Q="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJin5PvACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr2ZA//YwEUTIMP+uyx3AOqQ+9BrM9H/FTVoQtMh00XFf47M11OgRMp\r\nIEFqX93WeU7wBYSCwh478UkeRWmnaYyZU2SAGjeg1dlTTFZVyvJzez/94/F4\r\nDNr+Nu5VYazkuPKB0VGuCmJlFn0uQg1wUncGATn6FbGr2UaQ4NKUwHTORQe+\r\neGLUKqInmoXRaSrHdM0ppHWvrnryokgiAhQIt6tnDFGUGvVkuTDSCR/Ip8D7\r\n85EHihAlfE6r1+luEQvrM35vYieSfsvddcqAQy2m9wODYWYQ8YTd2Fh5GplW\r\n5bHxPSCqJd7yDL+mE9bOXom+pv+OaUwt84BiuzqwmifQ9yoRpHyNZBb9Hgee\r\npOoM2k/GADOvjuea02v+1htWb7mUdbU6lcEVIq+ix0IGE5EqmD8X0i0zqit8\r\nLwX2lNn41jyc2Z6hqHZ8ZxluaBuzgVATVqlPzDUp7Uau5FgDMBxl9FBHhgMF\r\nfPj+G6V1HMPJh4EWtRmtXgcvLT4SnrFB8aZ3gLJv/rdzIjJld6qViOjpTg/x\r\nGb08eLd2fZTkSnymMktN8GuAwlQBFhymL55g4os3FWiLZ/H3Wvx9CSiOCEPF\r\nChH38RL9epiKf2hSKwnqAXc3mRH7NQWyoBYCx5pw1worAGeSdM+wuA+bSn6G\r\nMgCwQxUcgl9oKLV89F8FcogYRVnHhMtDwD8=\r\n=+JNM\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alchie","email":"chesteralantagudin@gmail.com"},"directories":{},"maintainers":[{"name":"alchie","email":"chesteralantagudin@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gatsby-source-graphql_4.17.0-graphql-source-name.0_1654625263489_0.1860037866368851"},"_hasShrinkwrap":false}},"time":{"created":"2022-06-07T18:07:43.382Z","4.17.0-graphql-source-name.0":"2022-06-07T18:07:43.644Z","modified":"2022-06-07T18:07:43.838Z"},"maintainers":[{"name":"alchie","email":"chesteralantagudin@gmail.com"}],"description":"Gatsby plugin which adds a third-party GraphQL API to Gatsby GraphQL","homepage":"https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-source-graphql#readme","keywords":["gatsby","gatsby-plugin"],"repository":{"type":"git","url":"git+https://github.com/gatsbyjs/gatsby.git","directory":"packages/gatsby-source-graphql"},"author":{"name":"Mikhail Novikov","email":"freiksenet@gmail.com"},"bugs":{"url":"https://github.com/gatsbyjs/gatsby/issues"},"license":"MIT","readme":"# gatsby-source-graphql\n\nPlugin for connecting arbitrary GraphQL APIs to Gatsby's GraphQL. Remote schemas are stitched together by declaring an arbitrary type name that wraps the remote schema Query type (`typeName` below), and putting the remote schema under a field of the Gatsby GraphQL query (`fieldName` below).\n\n- [Example website](https://using-gatsby-source-graphql.netlify.app/)\n- [Example website source](https://github.com/gatsbyjs/gatsby/tree/master/examples/using-gatsby-source-graphql)\n\nThis source plugin does **not** support [incremental builds, cloud builds](https://support.gatsbyjs.com/hc/en-us/articles/360053099253-Gatsby-Builds-Full-Incremental-and-Cloud), and preview (on Gatsby Cloud). Please be aware that build times will be signficantly slower than regular source plugins as the size of your site goes past a hundred or so pages.\n\n## Install\n\n`npm install gatsby-source-graphql`\n\n## How to use\n\nIf the remote GraphQL API needs authentication, you should pass environment variables to the build process, so credentials aren't committed to source control. We recommend using [`dotenv`][dotenv], which will then expose environment variables. [Read more about dotenv and using environment variables here][envvars]. Then we can _use_ these environment variables via `process.env` and configure our plugin.\n\n```javascript\n// In your gatsby-config.js\nmodule.exports = {\n  plugins: [\n    // Simple config, passing URL\n    {\n      resolve: \"gatsby-source-graphql\",\n      options: {\n        // Arbitrary name for the remote schema Query type\n        typeName: \"SWAPI\",\n        // Field under which the remote schema will be accessible. You'll use this in your Gatsby query\n        fieldName: \"swapi\",\n        // Url to query from\n        url: \"https://swapi-graphql.netlify.app/.netlify/functions/index\",\n      },\n    },\n\n    // Advanced config, passing parameters to apollo-link\n    {\n      resolve: \"gatsby-source-graphql\",\n      options: {\n        typeName: \"GitHub\",\n        fieldName: \"github\",\n        url: \"https://api.github.com/graphql\",\n        // HTTP headers\n        headers: {\n          // Learn about environment variables: https://gatsby.dev/env-vars\n          Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,\n        },\n        // HTTP headers alternatively accepts a function (allows async)\n        headers: async () => {\n          return {\n            Authorization: await getAuthorizationToken(),\n          }\n        },\n        // Additional options to pass to node-fetch\n        fetchOptions: {},\n      },\n    },\n\n    // Advanced config, using a custom fetch function\n    {\n      resolve: \"gatsby-source-graphql\",\n      options: {\n        typeName: \"GitHub\",\n        fieldName: \"github\",\n        url: \"https://api.github.com/graphql\",\n        // A `fetch`-compatible API to use when making requests.\n        fetch: (uri, options = {}) =>\n          fetch(uri, { ...options, headers: sign(options.headers) }),\n      },\n    },\n\n    // Complex situations: creating arbitrary Apollo Link\n    {\n      resolve: \"gatsby-source-graphql\",\n      options: {\n        typeName: \"GitHub\",\n        fieldName: \"github\",\n        // Create Apollo Link manually. Can return a Promise.\n        createLink: pluginOptions => {\n          return createHttpLink({\n            uri: \"https://api.github.com/graphql\",\n            headers: {\n              Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,\n            },\n            fetch,\n          })\n        },\n      },\n    },\n  ],\n}\n```\n\n## How to Query\n\n```graphql\n{\n  # This is the fieldName you've defined in the config\n  swapi {\n    allSpecies {\n      name\n    }\n  }\n  github {\n    viewer {\n      email\n    }\n  }\n}\n```\n\n## Schema definitions\n\nBy default, the schema is introspected from the remote schema. The schema is cached in the `.cache` directory, and refreshing the schema requires deleting the cache (e.g. by restarting `gatsby develop`).\n\nTo control schema consumption, you can alternatively construct the schema definition by passing a `createSchema` callback. This way you could, for example, read schema SDL or introspection JSON. When the `createSchema` callback is used, the schema isn't cached. `createSchema` can return a GraphQLSchema instance, or a Promise resolving to one.\n\n```js\nconst fs = require(\"fs\")\nconst { buildSchema, buildClientSchema } = require(\"graphql\")\n\nmodule.exports = {\n  plugins: [\n    {\n      resolve: \"gatsby-source-graphql\",\n      options: {\n        typeName: \"SWAPI\",\n        fieldName: \"swapi\",\n        url: \"https://api.graphcms.com/simple/v1/swapi\",\n\n        createSchema: async () => {\n          const json = JSON.parse(\n            fs.readFileSync(`${__dirname}/introspection.json`)\n          )\n          return buildClientSchema(json.data)\n        },\n      },\n    },\n    {\n      resolve: \"gatsby-source-graphql\",\n      options: {\n        typeName: \"SWAPI\",\n        fieldName: \"swapi\",\n        url: \"https://api.graphcms.com/simple/v1/swapi\",\n\n        createSchema: async () => {\n          const sdl = fs.readFileSync(`${__dirname}/schema.sdl`).toString()\n          return buildSchema(sdl)\n        },\n      },\n    },\n  ],\n}\n```\n\n## Composing Apollo Links for production network setup\n\nNetwork requests can fail, return errors or take too long. Use [Apollo Link](https://www.apollographql.com/docs/react/api/link/introduction/) to\nadd retries, error handling, logging and more to your GraphQL requests.\n\nUse the plugin's `createLink` option to add a custom Apollo Link to your GraphQL requests.\n\nYou can compose different types of links, depending on the functionality you're trying to achieve.\nThe most common links are:\n\n- `@apollo/client/link/retry` for retrying queries that fail or time out\n- `@apollo/client/link/error` for error handling\n- `@apollo/client/link/http` for sending queries in http requests (used by default)\n\nFor more explanation of how Apollo Links work together, check out this Medium article: [Productionizing Apollo Links](https://medium.com/@joanvila/productionizing-apollo-links-4cdc11d278eb).\n\nHere's an example of using the HTTP link with retries (using [@apollo/client/link/retry](https://www.apollographql.com/docs/react/api/link/apollo-link-retry/)):\n\n```js\n// gatsby-config.js\nconst { createHttpLink, from } = require(`@apollo/client`)\nconst { RetryLink } = require(`@apollo/client/link/retry`)\n\nconst retryLink = new RetryLink({\n  delay: {\n    initial: 100,\n    max: 2000,\n    jitter: true,\n  },\n  attempts: {\n    max: 5,\n    retryIf: (error, operation) =>\n      Boolean(error) && ![500, 400].includes(error.statusCode),\n  },\n})\n\nmodule.exports = {\n  plugins: [\n    {\n      resolve: \"gatsby-source-graphql\",\n      options: {\n        typeName: \"SWAPI\",\n        fieldName: \"swapi\",\n        url: \"https://api.graphcms.com/simple/v1/swapi\",\n\n        // `pluginOptions`: all plugin options\n        //   (i.e. in this example object with keys `typeName`, `fieldName`, `url`, `createLink`)\n        createLink: pluginOptions =>\n          from([retryLink, createHttpLink({ uri: pluginOptions.url })]),\n      },\n    },\n  ],\n}\n```\n\n## Custom transform schema function (advanced)\n\nIt's possible to modify the remote schema, via a `transformSchema` option which customizes the way the default schema is transformed before it is merged on the Gatsby schema by the stitching process.\n\nThe `transformSchema` function gets an object argument with the following fields:\n\n- schema (introspected remote schema)\n- link (default link)\n- resolver (default resolver)\n- defaultTransforms (an array with the default transforms)\n- options (plugin options)\n\nThe return value is expected to be the final schema used for stitching.\n\nBelow an example configuration that uses the default implementation (equivalent to not using the `transformSchema` option at all):\n\n```js\nconst { wrapSchema } = require(`@graphql-tools/wrap`)\nconst { linkToExecutor } = require(`@graphql-tools/links`)\n\nmodule.exports = {\n  plugins: [\n    {\n      resolve: \"gatsby-source-graphql\",\n      options: {\n        typeName: \"SWAPI\",\n        fieldName: \"swapi\",\n        url: \"https://api.graphcms.com/simple/v1/swapi\",\n        transformSchema: ({\n          schema,\n          link,\n          resolver,\n          defaultTransforms,\n          options,\n        }) => {\n          return wrapSchema(\n            {\n              schema,\n              executor: linkToExecutor(link),\n            },\n            defaultTransforms\n          )\n        }\n    },\n  ]\n}\n```\n\nFor details, refer to [https://www.graphql-tools.com/docs/schema-wrapping](https://www.graphql-tools.com/docs/schema-wrapping).\n\nAn use case for this feature can be seen in [this issue](https://github.com/gatsbyjs/gatsby/issues/23552).\n\n## Refetching data\n\nBy default, `gatsby-source-graphql` will only refetch the data once the server is restarted. It's also possible to configure the plugin to periodically refetch the data. The option is called `refetchInterval` and specifies the timeout in seconds.\n\n```js\nmodule.exports = {\n  plugins: [\n    // Simple config, passing URL\n    {\n      resolve: \"gatsby-source-graphql\",\n      options: {\n        // Arbitrary name for the remote schema Query type\n        typeName: \"SWAPI\",\n        // Field under which the remote schema will be accessible. You'll use this in your Gatsby query\n        fieldName: \"swapi\",\n        // Url to query from\n        url: \"https://api.graphcms.com/simple/v1/swapi\",\n\n        // refetch interval in seconds\n        refetchInterval: 60,\n      },\n    },\n  ],\n}\n```\n\n## Performance tuning\n\nBy default, `gatsby-source-graphql` executes each query in a separate network request.\nBut the plugin also supports query batching to improve query performance.\n\n**Caveat**: Batching is only possible for queries starting at approximately the same time. In other words\nit is bounded by the number of parallel GraphQL queries executed by Gatsby (by default it is **4**).\n\nFortunately, we can increase the number of queries executed in parallel by setting the [environment variable](https://gatsby.dev/env-vars)\n`GATSBY_EXPERIMENTAL_QUERY_CONCURRENCY` to a higher value and setting the `batch` option of the plugin\nto `true`.\n\nExample:\n\n```shell\ncross-env GATSBY_EXPERIMENTAL_QUERY_CONCURRENCY=20 gatsby develop\n```\n\nWith plugin config:\n\n```js\nconst fs = require(\"fs\")\nconst { buildSchema, buildClientSchema } = require(\"graphql\")\n\nmodule.exports = {\n  plugins: [\n    {\n      resolve: \"gatsby-source-graphql\",\n      options: {\n        typeName: \"SWAPI\",\n        fieldName: \"swapi\",\n        url: \"https://api.graphcms.com/simple/v1/swapi\",\n        batch: true,\n      },\n    },\n  ],\n}\n```\n\nBy default, the plugin batches up to 5 queries. You can override this by passing\n`dataLoaderOptions` and set a `maxBatchSize`:\n\n```js\nconst fs = require(\"fs\")\nconst { buildSchema, buildClientSchema } = require(\"graphql\")\n\nmodule.exports = {\n  plugins: [\n    {\n      resolve: \"gatsby-source-graphql\",\n      options: {\n        typeName: \"SWAPI\",\n        fieldName: \"swapi\",\n        url: \"https://api.graphcms.com/simple/v1/swapi\",\n        batch: true,\n        // See https://github.com/graphql/dataloader#new-dataloaderbatchloadfn--options\n        // for a full list of DataLoader options\n        dataLoaderOptions: {\n          maxBatchSize: 10,\n        },\n      },\n    },\n  ],\n}\n```\n\nHaving 20 parallel queries with 5 queries per batch means we are still running 4 batches\nin parallel.\n\nEach project is unique so try tuning those two variables and see what works best for you.\nWe've seen up to 5-10x speed-up for some setups.\n\n### How batching works\n\nUnder the hood `gatsby-source-graphql` uses [DataLoader](https://github.com/graphql/dataloader)\nfor query batching. It merges all queries from a batch to a single query that gets sent to the\nserver in a single network request.\n\nConsider the following example where both of these queries are run:\n\n```js\n{\n  query: `query(id: Int!) {\n    node(id: $id) {\n      foo\n    }\n  }`,\n  variables: { id: 1 },\n}\n```\n\n```js\n{\n  query: `query(id: Int!) {\n    node(id: $id) {\n      bar\n    }\n  }`,\n  variables: { id: 2 },\n}\n```\n\nThey will be merged into a single query:\n\n```js\n{\n  query: `\n    query(\n      $gatsby0_id: Int!\n      $gatsby1_id: Int!\n    ) {\n      gatsby0_node: node(id: $gatsby0_id) {\n        foo\n      }\n      gatsby1_node: node(id: $gatsby1_id) {\n        bar\n      }\n    }\n  `,\n  variables: {\n    gatsby0_id: 1,\n    gatsby1_id: 2,\n  }\n}\n```\n\nThen `gatsby-source-graphql` splits the result of this single query into multiple results\nand delivers it back to Gatsby as if it executed multiple queries:\n\n```js\n{\n  data: {\n    gatsby0_node: { foo: `foo` },\n    gatsby1_node: { bar: `bar` },\n  },\n}\n```\n\nis transformed back to:\n\n```js\n[\n  { data { node: { foo: `foo` } } },\n  { data { node: { bar: `bar` } } },\n]\n```\n\nNote that if any query result contains errors the whole batch will fail.\n\n### Apollo-style batching\n\nIf your server supports apollo-style query batching you can also try\n[HttpLinkDataLoader](https://github.com/prisma-labs/http-link-dataloader).\nPass it to the `gatsby-source-graphql` plugin via the `createLink` option.\n\nThis strategy is usually slower than query merging but provides better error reporting.\n\n[dotenv]: https://github.com/motdotla/dotenv\n[envvars]: https://gatsby.dev/env-vars\n","readmeFilename":"README.md"}