Skip to content

Instantly share code, notes, and snippets.

@avishwakarma
Created February 4, 2019 10:15
Show Gist options
  • Save avishwakarma/63d8a3ba9081d1562915b68dd85c768f to your computer and use it in GitHub Desktop.
Save avishwakarma/63d8a3ba9081d1562915b68dd85c768f to your computer and use it in GitHub Desktop.
Apollo Client implementaion in Angular
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { Subscription } from 'rxjs';
import { ApolloModule, Apollo } from 'apollo-angular';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { setContext } from 'apollo-link-context';
import { onError } from 'apollo-link-error';
import { ApolloLink, split } from 'apollo-link';
import { HttpLink } from 'apollo-link-http';
import { WebSocketLink } from 'apollo-link-ws';
import { getMainDefinition } from 'apollo-utilities';
import { SessionService } from './common/session.service';
@NgModule({
declarations: [
...
],
imports: [
...
ApolloModule,
...
],
providers: [
...
],
bootstrap: [AppComponent]
})
export class AppModule{
constructor(
private apollo: Apollo,
private session: SessionService
) {
const protocol = environment.https ? 'https' : 'http';
// Creating new HttpLink for Apollo Client
const http = new HttpLink({
uri: `${protocol}://${environment.graphqlUrl}`,
});
// Creating new WebSocketLink for ApolloClient to support GraphQL subscriptions
const ws = new WebSocketLink({
uri: `ws:${environment.graphqlUrl}`,
options: {
reconnect: true
}
});
// authContext to set Authorization token for every request sent from client
const authContext = setContext(async (request, previousContext) => {
// Getting the token from the session service
const token = await this.session.getToken();
// return {} if token is not set yet
if(!token) {
return {}
}
// Set Authorization headers with token
return {
headers: {Authorization: `Bearer ${token}`}
}
});
// Error handling for GraphQL client
const error = onError(({graphQLErrors, networkError, response, operation}) => {
if(graphQLErrors) {
graphQLErrors.map(({message, path, type}) => {
// Destroy the session if INVALID_TOKEN receieved from the server
// Forcing user to login again
if(type === 'INVALID_TOKEN') {
this.session.destroy();
}
// Forcing user to login again if token is UNAUTHENTICATED
if(type === 'UNAUTHENTICATED') {
this.session.destroy();
}
// Loggin the GraphQL errors on the console
console.log(`[GraphQL Error]: Type: ${type}, Message: ${message}`, path);
});
}
// Login the Network errors
if(networkError) {
console.log(`[Network Error]:`, networkError);
}
});
// afterwareLink, Apollo link
const afterwareLink = new ApolloLink((operation, forward) => {
// tap to the forward reuqest operation
return forward(operation).map(response => {
// get the response headers
const {
response: {headers}
} = operation.getContext();
// check if headers recieved
if(headers) {
// get the token from the response header
const _token = headers.get('Authorization');
// check if token is not null
if(_token && _token !== 'null') {
// get playload for of the token
const payload = getPayload(_token);
// set the new token into the session
this.session.setToken(_token);
}
}
return response;
});
});
// creating the conditional link for http and ws requests
const link = split(({query}) => {
const { kind, operation } = getMainDefinition(query);
return kind === 'OperationDefinition' && operation === 'subscription';
}, ws, ApolloLink.from([authContext, error, afterwareLink, http]));
// creating the final Apollo client link with all the parameters
apollo.create({
link: link,
cache: new InMemoryCache(),
defaultOptions: {
query: {
fetchPolicy: 'network-only'
}
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment