Search code examples
graphqlapolloangular9graphql-subscriptions

Apollo Graphql with Angular with headers and Subscriptions


I need to add headers to my graphql requests with angular with subscriptions. but I didn't find any way. headers will be added if I only used headers without subscriptions. Also, subscriptions will works if I didn't add headers. But with both, it won't work. here is my code

import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { ApolloModule, Apollo, APOLLO_OPTIONS } from 'apollo-angular';
import { HttpLinkModule, HttpLink } from 'apollo-angular-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { ApolloLink, split } from 'apollo-link';
import { setContext } from 'apollo-link-context';
import { WebSocketLink } from 'apollo-link-ws';
import { getMainDefinition } from 'apollo-utilities';

const uri = 'http://localhost:5000/graphql';

export function provideApollo(httpLink: HttpLink) {
  const basic = setContext((operation, context) => ({
    headers: {
      Accept: 'charset=utf-8'
    }
  }));

  // Get the authentication token from local storage if it exists
  const token = localStorage.getItem('token');
  const auth = setContext((operation, context) => ({
    headers: {
      Authorization: `Bearer ${token}`
    },
  }));

  const subscriptionLink = new WebSocketLink({
    uri:
      'ws://localhost:5000/graphql',
    options: {
      reconnect: true,
      connectionParams: {
        authToken: localStorage.getItem('token') || null
      }
    }
  });

  const link = split(({ query }) => {
    const { kind } = getMainDefinition(query);
    return kind === 'OperationDefinition';
  }, subscriptionLink, ApolloLink.from([basic, auth, httpLink.create({ uri })]));



  // const link = ApolloLink.from([basic, auth, httpLink.create({ uri }), subscriptionLink]);
  const cache = new InMemoryCache();
  return {
    link,
    cache
  };
}

@NgModule({
  exports: [
    HttpClientModule,
    ApolloModule,
    HttpLinkModule
  ],
  providers: [{
    provide: APOLLO_OPTIONS,
    useFactory: provideApollo,
    deps: [HttpLink]
  }]
})
export class GraphQLModule { }

in here headers will not be added. Any Solutions?


Solution

  • import { NgModule } from "@angular/core";
    import { HttpClientModule, HttpHeaders } from "@angular/common/http";
    import { ApolloModule, Apollo, APOLLO_OPTIONS } from "apollo-angular";
    import { HttpLinkModule, HttpLink } from "apollo-angular-link-http";
    import { InMemoryCache } from "apollo-cache-inmemory";
    import { ApolloLink, split, from } from "apollo-link";
    import { setContext } from "apollo-link-context";
    import { WebSocketLink } from "apollo-link-ws";
    import { getMainDefinition } from "apollo-utilities";
    import ApolloClient from "apollo-client";
    
    const uri = "http://localhost:5000/graphql";
    
    const subscriptionLink = new WebSocketLink({
      uri: "ws://localhost:5000/graphql",
      options: {
        reconnect: true,
        connectionParams: {
          authToken: localStorage.getItem("token") || null,
        },
      },
    });
    
    const authMiddleware = new ApolloLink((operation: any, forward: any) => {
      operation.setContext({
        headers: new HttpHeaders().set(
          "Authorization",
          `Bearer ${localStorage.getItem("token")}` || null,
        ),
      });
    
      return forward(operation);
    });
    
    export function createApollo(httpLink: HttpLink) {
      return {
        link: from([
          authMiddleware,
          split(
            ({ query }) => {
              const { kind, operation } = getMainDefinition(query);
              return kind === "OperationDefinition" && operation === "subscription";
            },
            subscriptionLink,
            httpLink.create({
              uri: "http://localhost:5000/graphql",
            }),
          ),
        ]),
        cache: new InMemoryCache(),
      };
    }
    
    @NgModule({
      exports: [HttpClientModule, ApolloModule, HttpLinkModule],
      providers: [
        {
          provide: APOLLO_OPTIONS,
          useFactory: createApollo,
          deps: [HttpLink],
        },
      ],
    })
    export class GraphQLModule {}