Next.js starter your AI actually understands. Ship internal tools in days not weeks. Pre-order $199 $499 → [Get it now]

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.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author