Created
February 4, 2019 10:15
-
-
Save avishwakarma/63d8a3ba9081d1562915b68dd85c768f to your computer and use it in GitHub Desktop.
Apollo Client implementaion in Angular
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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