How to call a GraphQL query/mutation from an Express server backend?
Asked Answered
V

4

12

My frontend is localhost:3000, and my GraphQL server is localhost:3333.

I've used react-apollo to query/mutate in JSX land, but haven't made a query/mutation from Express yet.

I'd like to make the query/mutation here in my server.js.

server.get('/auth/github/callback', (req, res) => {
  // send GraphQL mutation to add new user
});

Below seems like the right direction, but I'm getting TypeError: ApolloClient is not a constructor:

const express = require('express');
const next = require('next');
const ApolloClient = require('apollo-boost');
const gql = require('graphql-tag');


// setup
const client = new ApolloClient({
  uri: 'http://localhost:3333/graphql'
});
const app = next({dev});
const handle = app.getRequestHandler();

app
  .prepare()
  .then(() => {
    const server = express();

    server.get('/auth/github/callback', (req, res) => {
      // GraphQL mutation
      client.query({
        query: gql`
          mutation ADD_GITHUB_USER {
            signInUpGithub(
              email: "[email protected]"
              githubAccount: "githubusername"
              githubToken: "89qwrui234nf0"
            ) {
              id
              email
              githubToken
              githubAccount
            }
          }
        `,
      })
        .then(data => console.log(data))
        .catch(error => console.error(error));
    });

    server.listen(3333, err => {
      if (err) throw err;
      console.log(`Ready on http://localhost:3333`);
    });
  })
  .catch(ex => {
    console.error(ex.stack);
    process.exit(1);
  });

This post mentions Apollo as the solution, but doesn't give an example.

How do I call a GraphQL mutation from Express server :3000 to GraphQL :3333?

Valor answered 6/2, 2019 at 18:5 Comment(5)
hi Chance, could you explain a little bit more about your issue? I don't understand... you said you've used react-apollo (React side...) but then you don't know how to query from React? I don't understand.Kellen
Server-side renderingDinkins
hey, @JVLobo - I updated my question.Valor
cool, more clear now :) I've posted an answer, hope it helpsKellen
I wouldn't use a fully-featured client to do server-side requests. You can use something really simple like graphql-request instead.Roxannaroxanne
V
3

This is more likely to be what you're looking for:

const { createApolloFetch } = require('apollo-fetch');

const fetch = createApolloFetch({
    uri: 'https://1jzxrj179.lp.gql.zone/graphql',
});


// Example # 01
fetch({
    query: '{ posts { title } }',
}).then(res => {
    console.log(res.data);
});


// Example # 02
// You can also easily pass variables for dynamic arguments
fetch({
    query: `
        query PostsForAuthor($id: Int!) {
            author(id: $id) {
                firstName
                posts {
                    title
                    votes
                }
            }
        }
    `,
    variables: { id: 1 },
}).then(res => {
    console.log(res.data);
});

Taken from this post, might be helpful to others as well: https://www.apollographql.com/blog/graphql/examples/4-simple-ways-to-call-a-graphql-api/

Vex answered 8/2, 2019 at 9:43 Comment(1)
For anyone still out there, apollo-fetch is officially deprecated now and will no longer be receiving future updates 😟 So I'd advise against following this answer. This leaves fetch, axios, or even graphql-request as possibly the best alternatives out there. Personally, I'm leaning more towards Prisma's graphql-request.Impoverished
C
2

You can use graphql-request, it is a simple GraphQL client.

const { request } = require('graphql-request');

request('http://localhost:3333/graphql', `mutation ADD_USER($email: String!, $password: String!) {
  createUser(email: $email, password: $password) {
    id
    email
  }
}`, {email: '[email protected]', password: 'Pa$$w0rd'})
.then(data => console.info(data))
.catch(error => console.error(error));

It also support CORS.

const { GraphQLClient } = require('graphql-request');

const endpoint = 'http://localhost:3333/graphql';
const client = new GraphQLClient(endpoint, {
  credentials: 'include',
  mode: 'cors'
});

client.request(`mutation ADD_USER($email: String!, $password: String!) {
  createUser(email: $email, password: $password) {
    id
    email
  }
}`, {email: '[email protected]', password: 'Pa$$w0rd'})
.then(data => console.info(data))
.catch(error => console.error(error));

I use it to make E2E tests.

Cowrie answered 8/2, 2019 at 23:29 Comment(0)
K
0

As you are getting ApolloClient with require instead of import I think you are missing this part:

// es5 or Node.js
const Boost = require('apollo-boost');
const ApolloClient = Boost.DefaultClient;

or

const ApolloBoost = require('apollo-boost');
const ApolloClient = ApolloBoost.default;

Try one of those and see if it works.

Kellen answered 7/2, 2019 at 21:6 Comment(4)
The 2nd did the trick, but now it's looking for a fetch: Error: fetch is not found globally and no fetcher passed, to fix pass a fetch for your environment like https://www.npmjs.com/package/node-fetch. >>> For example: import fetch from 'node-fetch'; import { createHttpLink } from 'apollo-link-http';Valor
I'm diving into this now... apollographql.com/docs/link/links/http.htmlValor
How can I require createHttpLink ?Valor
I guess something like const HttpLink = require("apollo-link-http").HttpLink; or const { HttpLink } = require('apollo-link-http'); should do itKellen
T
0

I'd like to add one more way to query from express. This is what I ended up with.

install required packages

npm install graphql graphql-tag isomorphic-fetch

write graphql on separate file (myQuery.js)

const gql = require('graphql-tag');
const query = gql`
    query($foo: String) {
      // Graphql query
    }
}

Main file

const { print } = require('graphql/language/printer');
const query = require('./myQuery');
require('isomorphic-fetch');

// other logic

const foo = "bar"
const token = "abcdef"

await fetch('https://example.com/graphql', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'authorization': `Bearer ${token}`,
    },
    body: JSON.stringify({ 
      query: `${print(query)}`,
      variables: { foo },
    }),
})
Tutelary answered 24/6, 2020 at 14:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.