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

Passing headers from Gateway to subservices #8

Closed
tvvignesh opened this issue Dec 13, 2020 · 4 comments
Closed

Passing headers from Gateway to subservices #8

tvvignesh opened this issue Dec 13, 2020 · 4 comments

Comments

@tvvignesh
Copy link

tvvignesh commented Dec 13, 2020

Hi @gmac - I was wondering what would be the right way to pass the headers from Gateway to subservices when doing typemerging. I am able to get the headers in the gateway but was wondering the right way to pass it on.

Since I am not using Apollo Link like here: apollographql/apollo-server#737 I was wondering how to do the same with a normal fetch executor also since the executor is getting built when the gateway starts up.

Looked up the examples in this repo but that is not discussed so far. Any tips? Thanks.

@gmac
Copy link
Owner

gmac commented Dec 13, 2020

The headers would pass through the remote executor function (makeRemoteExecutor), you’d add anything you want there. I don’t know all the options that an executor receives in addition to document and variables, but I would assume one is the GraphQL context object. So, you’d setup context however you want it in the gateway server, and then pass those values through as headers in the remote executor call.

@gmac
Copy link
Owner

gmac commented Dec 13, 2020

Report back on findings: does the exec function indeed receive the context object?

@yaacovCR
Copy link
Collaborator

https://www.graphql-tools.com/docs/remote-schemas#using-cross-fetch

See section below that about headers....

Receives context, and also info if you want to do something with that....

@tvvignesh
Copy link
Author

@yaacovCR @gmac Thanks for the response on the same. I have got it working now with some minor tweaks with reference from the link @yaacovCR shared and this repo. I had to add context to makeRemoteExecutorWithTimeout function as suggested and.

const makeRemoteExecutorWithTimeout = function(url:string, timeout = 1000) : AsyncExecutor {
  return async ({ document, variables, context }) => {

    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), timeout);

    try {
      const query = typeof document === 'string' ? document : print(document);

      let headers = {
        'Content-Type': 'application/json'
      };

      if (context) {
        headers = Object.assign(headers, context['headers']);
      }

      const fetchResult = await fetch(url, {
        method: 'POST',
        headers: headers,
        body: JSON.stringify({
          query, variables
        }),
        signal: controller.signal
      });
      return fetchResult.json();
    } catch (error) {
      return error.name === 'AbortError' ? new Error(`Request exceeded timeout of ${timeout}`) : error;
    } finally {
      clearTimeout(timeoutId);
    }
  };
};

Also add contextFactory from graphql-helix to return the headers as context

contextFactory: () => {
            return {
              headers: req.headers
            };
   },

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants