Closed cRicateau closed 4 years ago
@cRicateau were you able to figure this out? I have the same question
I had similar use-case and I was able to figure it out.
Basically instead of passing fetch
from node-fetch
or cross-fetch
to the constructor of HttpLink
you can pass function which modifies the headers and then calls the mentioned fetch
.
You can extend HttpLink
class and do something like this:
import { HttpLink } from 'apollo-link-http';
import { fetch } from 'cross-fetch';
import { Request } from 'express';
class HttpLinkWithHeaders extends HttpLink {
// Whole request or only headers if you want
private req: Request = null;
constructor() {
super({
uri: `....`,
fetch: (input: RequestInfo, init?: RequestInit) => {
// Modify init.headers based on this.req here
return fetch(input, init);
},
});
}
// Call this on every request
public setHtppRequest = (req: Request) => {
this.req = req;
};
}
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 } });
Thank you for reporting.
In the last few months, since the transition of many libraries under The Guild's leadership, We've reviewed and released many improvements and versions to graphql-cli, graphql-config and graphql-import.
We've reviewed graphql-binding
, had many meetings with current users and engaged the community also through the roadmap issue.
What we've found is that the new GraphQL Mesh library is covering not only all the current capabilities of GraphQL Binding, but also the future ideas that were introduced in the original GraphQL Binding blog post and haven't come to life yet.
And the best thing - GraphQL Mesh gives you all those capabilities, even if your source is not a GraphQL service at all!
it can be GraphQL, OpenAPI/Swagger, gRPC, SQL or any other source!
And of course you can even merge all those sources into a single SDK.
Just like GraphQL Binding, you get a fully typed SDK (thanks to the protocols SDKs and the GraphQL Code Generator), but from any source, and that SDK can run anywhere, as a connector or as a full blown gateway. And you can share your own "Mesh Modules" (which you would probably call "your own binding") and our community already created many of those! Also, we decided to simply expose regular GraphQL, so you can choose how to consume it using all the awesome fluent client SDKs out there.
If you think that we've missed anything from GraphQL Binding that is not supported in a better way in GraphQL Mesh, please let us know!
In the context of that particular issue - GraphQL Mesh transform
API to add and update the requests at any point in the process, so setting headers dynamically is easy.
We're looking forward for your feedback of how we can make your experience even better!
@cRicateau We also observed the memory leak when creating an instance of Binding
on every request. The solution suggested by @lambrojos to dynamically set headers did not work for us (not 100% sure if we did it correctly though). Our solution was to use https://github.com/prisma-labs/graphql-request which makes it very easy to set headers on the client instance at any time. We haven't found any graphql client that provides the same auto-generated methods for queries and mutations though, like this project does. Haven't really investigated if https://the-guild.dev/blog/graphql-mesh does this, as it seems to covering different needs and we just needed a simple nodejs graphql client.
@timotgl could you share a simple example in a repo? then we could PR it with a couple of options so you could compare
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 newHttpLink
and a newGraphQLServiceBinding
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 ofGraphQLServiceBinding
each time ?I use the function
getGraphqlClient
to create a graphql client in all my requests: