0

I have ApolloServer running where the frontend makes a query request and the ApolloService fetches the request and then performs a request with RESTDataSource to a third-party service, I receive a response with a header.

Currently, ApolloServer only parses the body through the resolver and sends it back to the client

I wanted to pass also the header received to the client

I don't know how to do that at the RESTDataSource level since I don't have access to the Apollo response

I hope this was clear enough to explain the problem

export abstract class myClass extends RESTDataSource {

getSomething() {
    const endpoint = this.endpointPath;
    return this.get(endpoint);
  }

async didReceiveResponse<T>(response, request): Promise<T | null> {
    // these are the response headers desired to have them sent back to the client
    console.log(response.headers);
    if (response.ok) {
      return this.parseBody(response) as any as Promise<T>;
    } else {
      throw await this.errorFromResponse(response);
    }
  }
}

In the appolloService initialization i have

const apolloServer = new ApolloServer({

   context: async ({ res, req }) => {
    // these headers are not the same as received from the getSomething() response above
    console.log(res.getHeaders)
   }
)}
  • You'd probably be better off extending your type model to include the fields that you want from the response and including them directly in your result type. – Michel Floyd Dec 23 '22 at 18:22
  • @MichelFloyd thank you for you answer, I cannot do that because the headers I receive are from a proxy so I won’t be able to modify the response and If I would modify the received response and map it to new object that would require to change my graphQL types everywhere. – Latrache Abdelfettah Dec 23 '22 at 20:21

1 Answers1

0

I solved the issue by passing the res to the context and accessing the response in the didReceiveResponse, then adding the headers needed.

adding a response to context

const apolloServer = new ApolloServer({
context: async ({ res, req }) => {
 return {
        res: res,
      };}

using the response to append the headers to it

async didReceiveResponse<T>(response, request): Promise<T | null> {
// use this.authHeader value in the class anywhere

this.context.res.setHeader(
  "x-is-request-cached",
  response.headers.get("x-is-request-cached") ?? false
);
this.context.res.setHeader(
  "x-request-cached-time",
  response.headers.get("x-request-cached-time")
);
if (response.ok) {
  return (await this.parseBody(response)) as any as Promise<T>;
} else {
  throw await this.errorFromResponse(response);
}}

by doing this you will achieve the desired outcome of passing the headers to the graphQl client