nuxt-graphql-request

Easy GraphQL client integration with Nuxt.js

Usage no npm install needed!

<script type="module">
  import nuxtGraphqlRequest from 'https://cdn.skypack.dev/nuxt-graphql-request';
</script>

README

nuxt-graphql-request

📡 GraphQL Request Module

ci npm version Dependencies npm downloads code style: prettier License: MIT

Easy Minimal GraphQL client integration with Nuxt.js.

Features

  • Most simple and lightweight GraphQL client.
  • Promise-based API (works with async / await).
  • Typescript support.
  • AST support.
  • GraphQL Loader support.

📖 Release Notes

Setup

Install with yarn:

yarn add nuxt-graphql-request graphql --dev

Install with npm:

npm install nuxt-graphql-request graphql --save-dev

nuxt.config.js

module.exports = {
  buildModules: ['nuxt-graphql-request'],

  graphql: {
    /**
     * An Object of your GraphQL clients
     */
    clients: {
      default: {
        /**
         * The client endpoint url
         */
        endpoint: 'https://swapi-graphql.netlify.com/.netlify/functions/index',
        /**
         * Per-client options overrides
         * See: https://github.com/prisma-labs/graphql-request#passing-more-options-to-fetch
         */
        options: {},
      },
      secondClient: {
        // ...client config
      },
      // ...your other clients
    },

    /**
     * Options
     * See: https://github.com/prisma-labs/graphql-request#passing-more-options-to-fetch
     */
    options: {},

    /**
     * Optional
     * default: true (this includes cross-fetch/polyfill before creating the graphql client)
     */
    useFetchPolyfill: true,

    /**
     * Optional
     * default: false (this includes graphql-tag for node_modules folder)
     */
    includeNodeModules: true,
  },
};

Runtime Config

If you need to supply your endpoints at runtime, rather than build time, you can use the Runtime Config to provide your values:

nuxt.config.js

module.exports = {
  publicRuntimeConfig: {
    graphql: {
      clients: {
        default: {
          endpoint: '<client endpoint>',
        },
        secondClient: {
          endpoint: '<client endpoint>',
        },
        // ...more clients
      },
    },
  },
};

Usage

Component

asyncData

import { gql } from 'nuxt-graphql-request';

export default {
  async asyncData({ $graphql, params }) {
    const query = gql`
      query planets {
        allPlanets {
          planets {
            id
            name
          }
        }
      }
    `;

    const planets = await $graphql.default.request(query);
    return { planets };
  },
};

methods/created/mounted/etc

import { gql } from 'nuxt-graphql-request';

export default {
  methods: {
    async fetchSomething() {
      const query = gql`
        query planets {
          allPlanets {
            planets {
              id
              name
            }
          }
        }
      `;

      const planets = await this.$graphql.default.request(query);
      this.$set(this, 'planets', planets);
    },
  },
};

Store actions (including nuxtServerInit)

import { gql } from 'nuxt-graphql-request';

// In store
export default {
  actions: {
    async fetchAllPlanets({ commit }) {
      const query = gql`
        query planets {
          allPlanets {
            planets {
              id
              name
            }
          }
        }
      `;

      const planets = await this.$graphql.default.request(query);
      commit('SET_PLANETS', planets);
    },
  },
};

GraphQL Request Client

Examples from the official graphql-request library.

Authentication via HTTP header

In nuxt.config.ts

// nuxt.config.ts

module.exports = {
  graphql: {
    clients: {
      default: {
        endpoint: 'https://swapi-graphql.netlify.com/.netlify/functions/index',
        options: {
          headers: {
            authorization: 'Bearer MY_TOKEN',
          },
        },
      },
    },
  },
};
Incrementally setting headers

If you want to set headers after the GraphQLClient has been initialised, you can use the setHeader() or setHeaders() functions.

// Set a single header
this.$graphql.default.setHeaders({ authorization: 'Bearer MY_TOKEN' });

// Override all existing headers
this.$graphql.default.setHeader('authorization', 'Bearer MY_TOKEN');
Set endpoint

If you want to change the endpoint after the GraphQLClient has been initialised, you can use the setEndpoint() function.

this.$graphql.default.setEndpoint(newEndpoint);
passing-headers-in-each-request

It is possible to pass custom headers for each request. request() and rawRequest() accept a header object as the third parameter

<script>
const requestHeaders = {
  authorization: 'Bearer MY_TOKEN',
};

export default {
  methods: {
    async fetchSomething() {
      const query = gql`
        query planets {
          allPlanets {
            planets {
              id
              name
            }
          }
        }
      `;

      // Overrides the clients headers with the passed values
      const planets = await this.$graphql.default.request(query, {}, requestHeaders);
      this.$set(this, 'planets', planets);
    },
  },
};
</script>

Passing more options to fetch

In nuxt.config.ts:

// nuxt.config.ts

module.exports = {
  graphql: {
    clients: {
      default: {
        endpoint: 'https://swapi-graphql.netlify.com/.netlify/functions/index',
        options: {
          credentials: 'include',
          mode: 'cors',
        },
      },
    },
  },
};

Or using setHeaders / setHeader:

// Set a single header
this.$graphql.default.setHeader('credentials', 'include');
this.$graphql.default.setHeader('mode', 'cors');

// Override all existing headers
this.$graphql.default.setHeaders({
  credentials: 'include',
  mode: 'cors',
});

Using GraphQL Document variables

<script>
import { gql } from 'nuxt-graphql-request';

export default {
  methods: {
    async fetchSomething() {
      const query = gql`
        query planets($first: Int) {
          allPlanets(first: $first) {
            planets {
              id
              name
            }
          }
        }
      `;

      const variables = { first: 10 };

      const planets = await this.$graphql.default.request(query, variables);
    },
  },
};
</script>

GraphQL Mutations

<script>
import { gql } from 'nuxt-graphql-request';

export default {
  methods: {
    async fetchSomething() {
      const query = gql`
        {
          Movie(title: "Inception") {
            releaseDate
            actors {
              fullname # "Cannot query field 'fullname' on type 'Actor'. Did you mean 'name'?"
            }
          }
        }
      `;

      try {
        const data = await this.$graphql.default.request(endpoint, query);
        console.log(JSON.stringify(data, undefined, 2));
      } catch (error) {
        console.error(JSON.stringify(error, undefined, 2));
        process.exit(1);
      }
    },
  },
};
</script>

Error handling

<script>
import { gql } from 'nuxt-graphql-request';

export default {
  methods: {
    async fetchSomething() {
      const mutation = gql`
        mutation AddMovie($title: String!, $releaseDate: Int!) {
          insert_movies_one(object: { title: $title, releaseDate: $releaseDate }) {
            title
            releaseDate
          }
        }
      `;

      const variables = {
        title: 'Inception',
        releaseDate: 2010,
      };

      const data = await this.$graphql.default.request(mutation, variables);
    },
  },
};
</script>

Receiving a raw response

The request method will return the data or errors key from the response. If you need to access the extensions key you can use the rawRequest method:

import { gql } from 'nuxt-graphql-request';

const query = gql`
  query planets($first: Int) {
    allPlanets(first: $first) {
      planets {
        id
        name
      }
    }
  }
`;

const variables = { first: 10 };

const { data, errors, extensions, headers, status } = await this.$graphql.default.rawRequest(
  endpoint,
  query,
  variables
);
console.log(JSON.stringify({ data, errors, extensions, headers, status }, undefined, 2));

File Upload

<script>
import { gql } from 'nuxt-graphql-request';

export default {
  methods: {
    handleFileUpload(file) {
      const mutation = gql`
        mutation uploadUserAvatar($userId: Int!, $file: Upload!) {
          updateUser(id: $userId, input: { avatar: $file })
        }
      `;

      const variables = { userId: 1, file };

      this.$graphql.default.request(mutation, variables);
    },
  },
};
</script>

FAQ

Why use nuxt-graphql-request over @nuxtjs/apollo?

Don't get me wrong, Apollo Client is great and well maintained by the vue / nuxt community, I used Apollo Client for 18months before switching to graphql-request.

However, as I am obsessed with performances, Apollo Client doesn't work for me at all:

  • I don't need another state management as the Vue ecosystem is enough (Vuex & Persisted data).
  • I don't need an extra ~120kb parsed in my app for fetching my data.
  • I don't need subscriptions as I use pusher.com, there are also alternatives for a WS client: http://github.com/lunchboxer/graphql-subscriptions-client

Why do I have to install graphql?

graphql-request uses a TypeScript type from the graphql package such that if you are using TypeScript to build your project and you are using graphql-request but don't have graphql installed TypeScript build will fail. Details here. If you are a JS user then you do not technically need to install graphql. However, if you use an IDE that picks up TS types even for JS (like VSCode) then it's still in your interest to install graphql so that you can benefit from enhanced type safety during development.

Do I need to wrap my GraphQL documents inside the gql template exported by graphql-request?

No. It is there for convenience so that you can get the tooling support like prettier formatting and IDE syntax highlighting. You can use gql from graphql-tag if you need it for some reason too.

What's the difference between graphql-request, Apollo and Relay?

graphql-request is the most minimal and simplest to use GraphQL client. It's perfect for small scripts or simple apps.

Compared to GraphQL clients like Apollo or Relay, graphql-request doesn't have a built-in cache and has no integrations for frontend frameworks. The goal is to keep the package and API as minimal as possible.

Does nuxt-graphql-request support mutations?

Sure, you can perform any GraphQL queries & mutations as before 👍

Development

  1. Clone this repository
  2. Install dependencies using yarn install or npm install
  3. Start development server using yarn dev or npm run dev

Roadmap

📑 License

MIT License