Angular Http

Angular HTTP client optimization for automated API communication and robust data fetching integration

Angular HTTP is a community skill for making HTTP requests in Angular applications, covering HttpClient usage, interceptors, error handling, request caching, retry strategies, and API service patterns.

What Is This?

Overview

Angular HTTP provides patterns for managing API communication in Angular applications using HttpClient. It covers HttpClient for typed GET, POST, PUT, and DELETE requests with observable response handling, interceptors for adding authentication headers, logging requests, and transforming responses globally, error handling with catchError operators for displaying user-friendly error messages, request caching using interceptors or service-level caching with shareReplay, and retry strategies with retryWhen and exponential backoff for transient failures. The skill enables developers to build robust API integration layers with consistent error handling and request management across the application.

Who Should Use This

This skill serves Angular developers building API integration layers with typed request handling, teams implementing authentication and logging interceptors, and engineers designing resilient HTTP communication with retry and caching patterns.

Why Use It?

Problems It Solves

Repeated authentication header logic across services creates maintenance burden. API errors without structured handling produce raw error messages in the UI. Identical requests from multiple components waste bandwidth without caching. Transient network failures cause immediate errors without retry opportunities.

Core Highlights

HttpClient provides typed request methods with observable responses. Interceptors chain middleware for headers, logging, and error handling. ShareReplay caches observable results for multiple subscribers. Retry operators handle transient failures with configurable strategies.

How to Use It?

Basic Usage

import { Injectable } from
  '@angular/core';
import { HttpClient } from
  '@angular/common/http';
import { Observable } from
  'rxjs';

interface User {
  id: string;
  name: string;
  email: string;
}

@Injectable({ providedIn:
  'root' })
export class UserService {
  private url =
    '/api/users';

  constructor(
    private http: HttpClient
  ) {}

  getAll():
    Observable<User[]> {
    return this.http.get<
      User[]>(this.url);
  }

  getById(
    id: string
  ): Observable<User> {
    return this.http.get<User>(
      `${this.url}/${id}`);
  }

  create(
    user: Omit<User, 'id'>
  ): Observable<User> {
    return this.http.post<User>(
      this.url, user);
  }

  update(
    id: string,
    data: Partial<User>
  ): Observable<User> {
    return this.http.put<User>(
      `${this.url}/${id}`,
      data);
  }

  delete(
    id: string
  ): Observable<void> {
    return this.http.delete<
      void>(
        `${this.url}/${id}`);
  }
}

Real-World Examples

import {
  HttpInterceptorFn } from
    '@angular/common/http';
import { inject } from
  '@angular/core';
import { catchError, retry,
  timer } from 'rxjs';

// Auth interceptor
export const authInterceptor:
  HttpInterceptorFn =
    (req, next) => {
      const auth =
        inject(AuthService);
      const token =
        auth.getToken();

      if (token) {
        req = req.clone({
          setHeaders: {
            Authorization:
              `Bearer ${token}`,
          },
        });
      }
      return next(req);
    };

// Retry interceptor
export const retryInterceptor:
  HttpInterceptorFn =
    (req, next) => {
      return next(req).pipe(
        retry({
          count: 3,
          delay: (error, count) =>
            timer(
              count * 1000),
        }),
        catchError((error) => {
          console.error(
            `Request failed: `
            + `${req.url}`,
            error);
          throw error;
        }),
      );
    };

// Register in app config:
// provideHttpClient(
//   withInterceptors([
//     authInterceptor,
//     retryInterceptor,
//   ])
// )

Advanced Tips

Use functional interceptors (HttpInterceptorFn) over class-based interceptors for simpler composition and tree-shaking. Implement request caching with shareReplay(1) on service observables to avoid duplicate API calls. Use HttpContext to pass metadata through interceptors for conditional behavior like skipping cache or authentication for specific requests.

When to Use It?

Use Cases

Build a typed API service layer with CRUD operations and error handling. Implement authentication token injection through a global interceptor. Create retry logic with exponential backoff for transient network failures.

Related Topics

Angular HttpClient, interceptors, RxJS operators, error handling, and API integration.

Important Notes

Requirements

Angular 17 or later for functional interceptors. provideHttpClient in application configuration. RxJS for observable operators like retry and catchError.

Usage Recommendations

Do: use typed generic parameters on HttpClient methods for response type safety. Implement error interceptors that transform HTTP errors into user-friendly messages. Use functional interceptors for new projects.

Don't: subscribe to HTTP observables without handling errors which causes unhandled rejections. Retry POST requests that are not idempotent which can create duplicate records. Cache responses that change frequently without invalidation logic.

Limitations

HttpClient returns cold observables that execute on each subscription requiring explicit caching. Interceptor order matters and incorrect ordering can cause authentication failures. Retry logic does not distinguish between retryable and non-retryable errors without custom classification. Testing HTTP interactions requires HttpTestingController setup for mocking responses in unit tests.