Cesar  Hamill

Cesar Hamill

1604048040

Using Apollo to Query GraphQL from Node.js

It’s a common scenario—you built a quick prototype, it worked great, and now management wants it live yesterday. Maybe you were accessing a third-party GraphQL endpoint and now you’re in a rush to get something out the door. One of your roadblocks? That endpoint doesn’t provide CORS headers. No more calling it directly from your frontend JavaScript app.

Do you need to create an Express app with routes for each data set you need? No way! In this tutorial, we will use the Apollo client library within a Node.js Express app to provide a middleman to your third-party endpoint, without the need to rewrite your GraphQL queries and mutations.

In addition to Apollo, there are several NPM libraries, like lokka and express-graphql, that we could use to abstract our third-party endpoint. Each of these libraries have their pros and cons. We’ll be using Apollo due to its popularity and the level of support it has as part of the Apollo Data Graph Platform.

Want to skip to the end? You can find all the source code for this tutorial on GitHub.

Getting Started

First, let’s get all our files and dependencies in place. Create a folder called nodejs-apollo-client and open it in your terminal of choice.

Now run npm init in your terminal to initialize NPM in the directory. Then execute the script below to install the dependencies.

npm install --save npm i apollo-cache-inmemory apollo-client apollo-link-http express graphql graphql-tag  node-fetch

Build a GraphQL Middleman

Create a new file named apollo.js. This file contains the real “meat” of our solution. It brokers requests between our Express application and the third-party GraphQL endpoint.

Let’s start by copying the following snippet into that file.

const gql = require("graphql-tag");
const ApolloClient = require("apollo-client").ApolloClient;
const fetch = require("node-fetch");
const createHttpLink = require("apollo-link-http").createHttpLink;
const setContext = require("apollo-link-context").setContext;
const InMemoryCache = require("apollo-cache-inmemory").InMemoryCache;

const httpLink = createHttpLink({
  uri: "https://insights.opentok.com/graphql",
  fetch: fetch
});

const client = new ApolloClient({
  link: httpLink,
  cache: new InMemoryCache()
});

The client object is an Apollo client. Because we’re running this code on the server-side, fetch isn’t available to us. So we’ll start by creating an HttpLink manually so we can inject node-fetch in place of the built-in browser fetch.

For our purposes, we’ll use the InMemoryCache object to handle caching data, but in your production solution, you’ll likely want to replace this with whatever caching solution you prefer.

Next, copy the snippet below into the apollo.js file.

<br />const query = async (req, res) => {
  if (!req.body || !req.body.query) {
    res.sendStatus(500);
    return;
  }

  const query = gql(req.body.query);
  let variables = undefined;
  if (req.body.variables) {
    variables = JSON.parse(decodeURIComponent(req.body.variables));
  }

  try {
    const result = await client.query({
      query,
      variables
    });
    res.json(result);
  } catch (err) {
    console.log(err);
    res.sendStatus(500).send(JSON.stringify(err));
  }
};

const mutate = async (req, res) => {
  if (!req.body || !req.body.query) {
    res.sendStatus(500);
    return;
  }

  const query = gql(req.body.query);
  let variables = undefined;
  if (req.body.variables) {
    variables = JSON.parse(decodeURIComponent(req.body.variables));
  }

  try {
    const result = await client.mutate({
      query,
      variables
    });
    res.json(result);
  } catch (err) {
    console.log(err);
    res.sendStatus(500).send(JSON.stringify(err));
  }
};

These functions (query and mutate) take a request, pull query/mutate and variable information from the body, and then forward those parameters using the client object.

Finally, we create an apollo method and export it so we can use it in the Express workflow later. This function inspects the incoming request and forwards it to the appropriate (mutate or query) function.

<br />const apollo = async (req, res, next) => {
  switch (req.method) {
    case "POST":
    case "PUT":
      await mutate(req, res);
      break;

    case "GET":
    default:
      await query(req, res);
  }

  next();
};

module.exports = apollo;

#graphql #apollo #node #database #developer

Using Apollo to Query GraphQL from Node.js