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

Supply custom headers to queries #521

Closed
marktani opened this issue Aug 9, 2016 · 9 comments
Closed

Supply custom headers to queries #521

marktani opened this issue Aug 9, 2016 · 9 comments

Comments

@marktani
Copy link
Contributor

marktani commented Aug 9, 2016

The documentation shows how to add a authorization header:
Supply req.options.headers.authorization in a middleware.

How can we add a custom header my-custom-header with value header:header-value to all queries?

@stubailo
Copy link
Contributor

stubailo commented Aug 9, 2016

Yep - you can do it the same way. Have you tried it? req.options.headers["my-custom-header"] = "header:header-value"

@stubailo stubailo closed this as completed Aug 9, 2016
@fikriauliya
Copy link

Can the header value dynamically assigned upon .query call?
So far I haven't found a way to add additional parameters to .query which could be read in middleware, is there?

@helfer
Copy link
Contributor

helfer commented Mar 10, 2017

@fikriauliya it's not currently possible to pass additional parameters to query that are passed to the middleware layer. Could you describe your use-case?

@fikriauliya
Copy link

fikriauliya commented Mar 13, 2017

I have multiple GraphQL endpoints. As suggested #84 (comment), instead of creating multiple Apollo client, I created a proxy server to dispatch a GraphQL query to the corresponding server.

The way the proxy determine where to dispatch to is by HTTP header
(e.g. service: tracker => goes to tracker server, service: transaction, etc).
And this HTTP Header should be dynamically injected during apolloClient.query via one of its parameter.

apolloClient.query({ variable, query, service: 'tracker'}) --> Apollo middleware converts service: tracker to HTTP Header --> graphql.domain.com checks the header --> tracker.domain.com

@stubailo
Copy link
Contributor

I think the goal of doing the proxying on the server should be that the client is not aware of which server it is talking to. Perhaps you can use the root field names of the query? I feel like hard coding which graphql service you are talking to in each component might make things very hard to change down the road.

@fikriauliya
Copy link

fikriauliya commented Mar 14, 2017

Perhaps you can use the root field names of the query?

Thought about the same as well @stubailo . But I think there are two problems with that approach:

  1. The root field name may be shared among multiple services. e.g.:
me {
  recommendation { } => goes to recommendation service
}

and

me {
  profile { } => goes to profile service
}
  1. The proxy server may do more by decoding the GraphQL query and match on recommendation and profile fields instead. But I am afraid of the overhead (compared to simply match on HTTP Header which could be done in Nginx without any GraphQL server)

@fikriauliya
Copy link

Rethinking again, my approach above couldn't handle single query which need to retrieve from multiple servers:

me {
  recommendation { } => goes to recommendation service
  profile { } => goes to profile service
}

Now I am thinking to use approach (2) above: Instead of having simple Nginx proxy server, put GraphQL proxy server on top of Nginx, decode the JSON query, and dispatch based on JSON query.

Or do you have better alternatives?

@ProjectCheshire
Copy link

Came across this, also. Basically looking to aggregate many data sources under a single graphql api. Eg. some rest, but also some graphql endpoints

ala api gateway'ish. Coming to similar conclusion of having resolvers that dispatch to different network interfaces/connectors.

so
App layer (views/internal server app specific concerns)->graphql API gateway-> [1..n] endpoints (rest, another graphql api, traditional data stores, geodata, whatev)

Completely off base?

@webmobiles
Copy link

webmobiles commented Nov 26, 2017

set header value dynamically is messy
but if you add customer headers in your client, don't forget to add those fields in your 'Access-Control-Allow-Headers' on your server side, because browser CORS preflight ( request that uses the HTTP OPTIONS)

SERVER:

server.use('/graphql', (req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With, myCustomHeader1, myCustomHeader2,');
  if (req.method === 'OPTIONS') {
    res.sendStatus(200);
  } else {
    next();
  }
});

CLIENT:


  (..)
  networkInterface.use([{
    applyMiddleware(req, next) {
      if (!req.options.headers) {
        req.options.headers = {}; // Create the header object if needed.
      }
      req.options.headers.authorization = session.token ? `Bearer ${session.token}` : null;
      if (session.token) {
        req.options.headers.myCustomHeader1   =  something...;
        req.options.headers.myCustomHeader2  =  something...;
      }
      next();
    },
  }]);
  (..)

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

No branches or pull requests

6 participants