Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

run apollo-client in node environment throws error. #3578

Closed
forclan opened this issue Jun 13, 2018 · 6 comments
Closed

run apollo-client in node environment throws error. #3578

forclan opened this issue Jun 13, 2018 · 6 comments
Assignees

Comments

@forclan
Copy link

forclan commented Jun 13, 2018

Intended outcome:
execute normally in node environment.

Actual outcome:
throw 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.

How to reproduce the issue:

// create a new ts project and typings follow
import gql from 'graphql-tag';
import ApolloClient from 'apollo-boost';
import fetch from 'node-fetch';

const uri = 'https://w5xlvm3vzz.lp.gql.zone/graphql';
const client = new ApolloClient({
    uri,
    fetchOptions: {
        fetch: fetch as any
    }
});

client
    .query({
        query: gql`
            {
                rates(currency: "USD") {
                    currency
                }
            }
        `
    })
    .then(result => console.log(result));

execute:

ts-node src/index.ts

Versions
"dependencies": {
"apollo-boost": "^0.1.8",
"graphql": "^0.13.2",
"graphql-tag": "^2.9.2",
"node-fetch": "^2.1.2",
"react-apollo": "^2.1.4"
},
"devDependencies": {
"@types/node-fetch": "^2.1.1"
}

code error
it seems that is a code error in apollo-boost.

in apollo-boost/src/index.ts, DefaultClient call new HttpLink(xxx) to create a HttpLink:

    const httpLink = new HttpLink({
      uri: uri || '/graphql',
      fetchOptions: fetchOptions || {},
      credentials: credentials || 'same-origin',
      headers: headers || {},
    });

and HttpLink is defined in apollo-link-http, which calls createHttpLink:

export class HttpLink extends ApolloLink {
  public requester: RequestHandler;
  constructor(opts?: HttpLink.Options) {
    super(createHttpLink(opts).request);
  }
}

in createHttpLink it will access fetch in param:

export const createHttpLink = (linkOptions: HttpLink.Options = {}) => {
  let {
    uri = '/graphql',
    // use default global fetch is nothing passed in
    fetch: fetcher,
    includeExtensions,
    useGETForQueries,
    ...requestOptions
  } = linkOptions;

  // dev warnings to ensure fetch is present
  checkFetcher(fetcher);
  // omit other code
}

fetch does exists in linkOptions but exists in linkOptions.fetchOptions, so fetcher is undefined ans call checkFetcher(fetcher); throws error.

@hwillson
Copy link
Member

Thanks @forclan - this is actually working as designed, but it is definitely a bit confusing. Apollo Boost doesn't let you set a fetch (as you've found out, passing one in via fetchOptions won't work). For now your best bet is to eject from apollo-boost, and use the full apollo-client instead. Then when you define your HttpLink, you can properly set the fetch option.

I've marked this as a bug though since apollo-boost should work on the server, and allow a custom fetcher to be defined. If anyone is interested in adjusting boost to accept a fetch param, which will the be passed into the HttpLink instance, that would be awesome!

@hwillson hwillson removed their assignment Jun 13, 2018
@hwillson hwillson added 🙏 help-wanted 🏃‍♂️ medium-priority 📚 good-first-issue Issues that are suitable for first-time contributors. labels Jun 13, 2018
@mbaranovski
Copy link
Contributor

mbaranovski commented Jun 14, 2018

@hwillson I'm happy to take that one. Just tell me, the current behaviour is expected (in the browser) but you're suggesting to add fetch as a param to ApolloBoost then should I somehow check if we're running it in the browser/node.js environment and only allow it on node.js env or just simply add fetch param regardless of environment?

@hwillson
Copy link
Member

hwillson commented Jul 9, 2018

Sorry for the delay @mbaranovski - I meant add the fetch param regardless (which you've done in your PR). Thanks!

@forclan
Copy link
Author

forclan commented Jul 12, 2018

I'will close the issue since code is merged.

@forclan forclan closed this as completed Jul 12, 2018
@borisyordanov
Copy link

@hwillson Do we have to specify the fetch param? Can't we just use a global unfetch polyfill

@iki
Copy link

iki commented Apr 27, 2020

@borisyordanov unfetch is for js in browser, there we use it. In node.js, we need to pass a fetch lib like node-fetch.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 16, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants