How to integrate Angular with GraphQL API
Integrating Angular with a GraphQL API requires Apollo Client, which provides caching, reactive queries, and typed operations that REST clients lack.
As the creator of CoreUI with Angular development experience since 2014, I’ve used Apollo Angular in enterprise dashboards where the flexibility of GraphQL significantly reduced over-fetching and simplified data management.
The setup involves installing Apollo Angular, configuring the client with your GraphQL endpoint, and using the Apollo service to execute queries and mutations in your components.
Once configured, Apollo handles caching and state management for you automatically.
Install Apollo Angular and configure the client.
ng add apollo-angular
// graphql.provider.ts
import { ApplicationConfig } from '@angular/core'
import { provideApollo } from 'apollo-angular'
import { HttpLink } from 'apollo-angular/http'
import { InMemoryCache } from '@apollo/client/core'
import { inject } from '@angular/core'
export const graphqlProvider = provideApollo(() => {
const httpLink = inject(HttpLink)
return {
link: httpLink.create({ uri: 'https://api.example.com/graphql' }),
cache: new InMemoryCache()
}
})
// app.config.ts
import { ApplicationConfig } from '@angular/core'
import { provideHttpClient } from '@angular/common/http'
import { graphqlProvider } from './graphql.provider'
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(),
graphqlProvider
]
}
ng add apollo-angular configures the module automatically. InMemoryCache caches query results by type and ID, so repeated queries for the same data don’t hit the network.
Running a Query
Use Apollo.watchQuery to execute a query and reactively update the UI.
// users.component.ts
import { Component, OnInit } from '@angular/core'
import { CommonModule } from '@angular/common'
import { Apollo, gql } from 'apollo-angular'
const GET_USERS = gql`
query GetUsers {
users {
id
name
email
}
}
`
@Component({
selector: 'app-users',
standalone: true,
imports: [CommonModule],
template: `
<div *ngIf="loading">Loading...</div>
<ul *ngIf="users">
<li *ngFor="let user of users">{{ user.name }}</li>
</ul>
<p *ngIf="error">{{ error }}</p>
`
})
export class UsersComponent implements OnInit {
users: any[] = []
loading = true
error = ''
constructor(private apollo: Apollo) {}
ngOnInit(): void {
this.apollo.watchQuery({ query: GET_USERS })
.valueChanges
.subscribe({
next: ({ data, loading }) => {
this.users = (data as any).users
this.loading = loading
},
error: (err) => {
this.error = err.message
this.loading = false
}
})
}
}
watchQuery returns a QueryRef with a valueChanges observable. The observable emits whenever the cache is updated, so the UI re-renders automatically when related mutations write new data.
Running a Mutation
Execute a mutation to create or modify data.
import { Component } from '@angular/core'
import { Apollo, gql } from 'apollo-angular'
const CREATE_USER = gql`
mutation CreateUser($name: String!, $email: String!) {
createUser(name: $name, email: $email) {
id
name
email
}
}
`
@Component({
selector: 'app-create-user',
standalone: true,
template: `
<button (click)="create()">Create User</button>
`
})
export class CreateUserComponent {
constructor(private apollo: Apollo) {}
create(): void {
this.apollo.mutate({
mutation: CREATE_USER,
variables: { name: 'Alice', email: '[email protected]' }
}).subscribe({
next: ({ data }) => console.log('Created:', data),
error: (err) => console.error(err)
})
}
}
apollo.mutate() sends a GraphQL mutation to the server. Pass variables as a plain object matching the mutation’s parameter types. Apollo automatically updates the cache for types it can identify by ID.
Adding Auth Headers
Attach a Bearer token to every GraphQL request.
import { ApolloLink } from '@apollo/client/core'
import { setContext } from '@apollo/client/link/context'
const authLink = setContext((_, { headers }) => {
const token = localStorage.getItem('token')
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : ''
}
}
})
// In graphql.provider.ts
link: authLink.concat(httpLink.create({ uri: '/graphql' }))
setContext creates a link that runs before every request. Chaining it with concat before the HTTP link ensures the auth header is added to all queries and mutations automatically.
Best Practice Note
This is the same Apollo setup pattern we reference in CoreUI Angular templates for data-heavy dashboards. Use apollo.query (not watchQuery) for one-time fetches where you don’t need reactive updates. For REST APIs without GraphQL, see how to integrate Angular with REST API instead. Always generate TypeScript types from your GraphQL schema using GraphQL Code Generator to get full type safety on query results.



