Using ApolloClient with node.js. "fetch is not found globally and no fetcher passed"
Asked Answered
O

6

41

I am attempting to use an Apollo Client on a node.js server to interface with another GraphQL API using the following code:

import fetch from 'node-fetch'
import { createHttpLink } from 'apollo-link-http'

import ApolloClient from 'apollo-boost'
import { API_URL } from '...'

const client = new ApolloClient({
  link: createHttpLink({
    uri: API_URL,
    fetch: fetch,
  }),
})

Which yields the following error:

module initialization error: 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';

const link = createHttpLink({ uri: '/graphql', fetch: fetch });
at Object.checkFetcher (/var/task/node_modules/apollo-link-http-common/lib/bundle.umd.js:78:19)
at createHttpLink (/var/task/node_modules/apollo-link-http/lib/bundle.umd.js:32:30)
at new HttpLink (/var/task/node_modules/apollo-link-http/lib/bundle.umd.js:203:38)
at new DefaultClient (/var/task/node_modules/apollo-boost/lib/index.js:80:24)

I understand that the Apollo Client by default is expecting to be run in a browser context where a fetch method will be available, and that in a node.js I need to polyfill or otherwise provide a fetch method, but I having trouble figuring out exactly how to do this.

Following the example code at https://www.apollographql.com/docs/link/#apollo-client it appears that I should be able to pass this information in using the link option, and reading the apollo-boost source code seems to suggest that you can pass this information in using fetcherOptions, but neither of these solutions seem to work.

Can anyone provide some example code for initializing an Apollo Client in node.js with a fetcher?

For reference here is my package.json

{
  "name": "API-Service",
  "version": "1.0.0",
  "description": "",
  "private": true,
  "scripts": {},
  "dependencies": {
    "apollo-boost": "^0.1.6",
    "apollo-link-http": "^1.5.4",
    "graphql": "^0.13.2",
    "babel-polyfill": "^6.26.0",
    "json-rules-engine": "^2.1.0",
    "node-fetch": "^2.1.2",
    "mysql": "^2.15.0"
  }
}
Octennial answered 4/6, 2018 at 21:25 Comment(1)
I tried all of the suggestions below, none of them works I would always get teh error Invariant Violation: 1... (or that self is undefined when using whatwg-fetch)... Is there another solution?Rivkarivkah
O
39

It turns out that the ApolloClient provided by the apollo-boost library does not accept a link option. Switching to use the vanilla apollo-client allows you to specify your fetching mechanism.

Although apollo-boost and apollo-client both export an ApolloClient in the docs, they take wildly different options.

import fetch from 'node-fetch'
import { createHttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'

import ApolloClient from 'apollo-client'
import { API_URL } from '...'

const client = new ApolloClient({
  link: createHttpLink({
    uri: API_URL,
    fetch: fetch,
  }),
  cache: new InMemoryCache(),
})
Octennial answered 4/6, 2018 at 22:31 Comment(2)
does it mean that we cannot use apollo-boost?Constitute
Still not working, with this I get undefined is not an object.Zofiazoha
G
44

If you still want to use Apollo Boost in Node.js but need to polyfill the native fetch API of the browser, try out cross-fetch. I used it for my minimal example over here. And that's how it can be used after installing it:

import 'cross-fetch/polyfill';
import ApolloClient from 'apollo-boost';

const client = new ApolloClient({
  uri: 'https://api.domain.com/graphql',
});
Gemoets answered 6/6, 2018 at 11:31 Comment(4)
This worked for me using react native and Jest! ThanksColleencollege
this is not working with React and Jest, do we have to make any other changes in jest config or so?Constitute
Still getting fetch is not globally and no fetcher passed...Zofiazoha
Solved the exact same error that jest showed to me. +1 :)Cleanse
O
39

It turns out that the ApolloClient provided by the apollo-boost library does not accept a link option. Switching to use the vanilla apollo-client allows you to specify your fetching mechanism.

Although apollo-boost and apollo-client both export an ApolloClient in the docs, they take wildly different options.

import fetch from 'node-fetch'
import { createHttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'

import ApolloClient from 'apollo-client'
import { API_URL } from '...'

const client = new ApolloClient({
  link: createHttpLink({
    uri: API_URL,
    fetch: fetch,
  }),
  cache: new InMemoryCache(),
})
Octennial answered 4/6, 2018 at 22:31 Comment(2)
does it mean that we cannot use apollo-boost?Constitute
Still not working, with this I get undefined is not an object.Zofiazoha
M
25

You can add fetch option directly to the ApolloClient from apollo-boost. Here is the example code

Ref. https://www.apollographql.com/docs/react/essentials/get-started/#configuration-options

import ApolloClient from 'apollo-boost';
import fetch from 'node-fetch';

const client = new ApolloClient({
    fetch: fetch
});

Tested with apollo-boost version 0.4.3

Misshapen answered 9/8, 2019 at 8:53 Comment(5)
THANK YOU ! I confirmed this also works with @apollo/react-hooks 3.1.0 and apollo-boost 0.4.4 inside next.js 9.0.5. 👍Rube
This is exactly the solution that I come up with for Jest as well.Vesicate
Thanks, works with next 9.1.4 and apollo-boost 0.4.4, too!Unimpeachable
This works for me as well for the latest version (at this time) of Apollo boostUpbeat
Still not working, with this I get undefined is not an object.Zofiazoha
K
16

Try cross-fetch without a polyfill in node.

This even works with typescript. (conversely, node-fetch's type is incompatible with the standard whatwg fetch spec.)

import fetch from 'cross-fetch'

const httpLink = new HttpLink({
  uri: "<your-uri>",
  fetch,
})
Kalila answered 1/2, 2020 at 4:27 Comment(0)
A
4

You can use the whatwg-fetch polyfill:

yarn add whatwg-fetch

The installation instructions depend on your usage (e.g Babel, Webpack etc.) and are in the provided link.

In my case I needed the polyfill for my Jest tests so I just put this in my test setup file:

import 'whatwg-fetch';
Autotype answered 12/8, 2018 at 12:36 Comment(0)
C
0

I had that exact error, but fortunately I had already included node-fetch in my project, so I have imported it and associated it to the Apollo client.:

import fetch from 'node-fetch';
import ApolloClient from 'apollo-boost';
import {targetServer} from "./apiConstants";
import { gql } from "apollo-boost";

const client = new ApolloClient({
    fetch: fetch,
    uri: targetServer + '/graphql',
});

and in my package.json this is what I have:

{
  "name": "learn-starter",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  },
  "dependencies": {
    "@apollo/react-hooks": "^3.1.5",
    "apollo-boost": "^0.4.9",
    "graphql": "^15.1.0",
    "next": "9.3.5",
    "node-fetch": "^2.6.0",
    ...
  }
}
Cestoid answered 21/6, 2020 at 16:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.