question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to dynamically update the link headers in the binding instance ?

See original GitHub issue

I use graphql-binding in an express server to query another graphql server. On each request, I need to pass a header whose value changes everytime (it comes from the express req object and it is used for tracing ). I create a new HttpLink and a new GraphQLServiceBinding instance each time, but it creates a memory leak on my server (see code below).

Is there a way to dynamically change the headers in my link instance without re-creating a new instance of GraphQLServiceBinding each time ?

I use the function getGraphqlClient to create a graphql client in all my requests:

import { introspectSchema } from 'graphql-tools'
import fetch from 'node-fetch'
import { HttpLink } from 'apollo-link-http'
import { Binding } from 'graphql-binding'
import { makeRemoteExecutableSchema } from 'graphql-tools'

const graphqlServerUrl = process.env.GRAPHQL_URL

class GraphQLServiceBinding extends Binding {
  constructor(introspectedSchema, link) {
    const schema = makeRemoteExecutableSchema({
      link,
      schema: introspectedSchema,
    })

    super({ schema })
  }
}

let cachedSchema = null

async function getCachedSchema(link) {
  if (cachedSchema) return cachedSchema
  cachedSchema = await introspectSchema(link)
  return cachedSchema
}

// function getGraphqlClient is used to instantiate a new binding with specific headers
export const getGraphqlClient = async (graphQLServerUrl, headers = {}) => {
  const uri = graphQLServerUrl || process.env.GRAPHQL_URL
  if (!uri) {
    throw new Error('GRAPHQL_URL variable is mandatory')
  }

  try {
    // the headers change on every request
    const link = new HttpLink({ uri, fetch, headers })
    // the schema doesn't change
    const schema = await getCachedSchema(link)
    const binding = new GraphQLServiceBinding(schema, link)

    return binding
  } catch (err) {
    console.error(
      `Error introspecting remote schema on url ${graphQLServerUrl}`
    )
    throw err
  }
}

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:3
  • Comments:6

github_iconTop GitHub Comments

3reactions
lambrojoscommented, Dec 16, 2018

You can use the apollo-link-context module to set headers based on the request context:

const fetch = require('node-fetch');
const { Binding } = require('graphql-binding');
const { HttpLink } = require('apollo-link-http');
const { makeRemoteExecutableSchema, introspectSchema } = require('graphql-tools');
const { setContext } = require('apollo-link-context');

const http = new HttpLink({ uri: process.env.GRAPHQL_ENDPOINT, fetch });
const link = setContext((request, { graphqlContext }) => (
  graphqlContext ? {
    headers: {
      Authorization: `Bearer ${graphqlContext.auth}`,
    },
  } : {})).concat(http);

const schemaPromise = introspectSchema(link);

module.exports.graphql = schemaPromise
  .then(typeDefs => new class GraphQLBinding extends Binding {
    constructor() {
      super({
        schema: makeRemoteExecutableSchema({ link, schema: typeDefs }),
      });
    }
  }());

You can specify the context as a property of the third parameter in your bindings:

  const auth = 'auth token';
  const result = await bindings.query.whatevers({
    skip: 0,
    limit: 10,
  }, `{ items { id, body }}`, { context: { auth } });
0reactions
Urigocommented, Aug 18, 2020

@timotgl could you share a simple example in a repo? then we could PR it with a couple of options so you could compare

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to make dynamic headers in word - YouTube
In this video I show you how to make dynamic headers in word. In this example I make headers that match my chapter...
Read more >
How to dynamically change header based on AngularJS ...
I just discovered a nice way to set your page title if you're using routing: JavaScript: var myApp = angular.module('myApp', ['ngResource']) myApp.config( ...
Read more >
Changing web service binding endpoints dynamically at run ...
You change the URL of the target service in the web service binding by overwriting the target URL in the SOAP header. Following...
Read more >
Allow dynamic bindings to change a lens header in compact ...
Requirement: Allow dynamic bindings to change a lens header in compact form. Why is needed? Clear communication of what we display is very ......
Read more >
Using HTTP to Send and Receive Dynamic Headers
A request is sent to the server by the client. The server accepts the request and the HTTP connection is then closed by...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found