Forge API

Angular Tutorial

How to Use a Mock API in Angular While Your Backend Is Being Built

Connect Angular to Forge API through HttpClient and a reusable API service, then replace the backend URL when your production API is ready.

Angular already encourages applications to keep network logic in services. That makes it a natural fit for developing against Forge API while keeping the production backend replaceable.

What we are building

Angular component

ApiService

environment.apiBaseUrl

Forge API

1. Create your Forge API endpoint

Add a /products endpoint to your Forge API project. Your Angular application will call a URL similar to:

text
https://apis.getforgeapi.com/YOUR_PROJECT_KEY/products

Need your mock backend?

Create a Forge API endpoint and use it immediately from your Angular application.

Create your mock API

2. Configure the API base URL

src/environments/environment.tsts
export const environment = {
  apiBaseUrl:
    "https://apis.getforgeapi.com/YOUR_PROJECT_KEY",
};

Keeping this value outside your components means the backend host can change without rewriting the UI.

3. Enable Angular HttpClient

src/app/app.config.tsts
import { ApplicationConfig } from "@angular/core";
import { provideHttpClient } from "@angular/common/http";

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(),
  ],
};

Standalone Angular setup

This example uses the modern standalone Angular configuration with provideHttpClient().

4. Create a reusable API service

src/app/services/api.service.tsts
import { Injectable, inject } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { environment } from "../environments/environment";

@Injectable({
  providedIn: "root",
})
export class ApiService {
  private readonly http = inject(HttpClient);

  getApiRes<T>(endpoint: string) {
    const path = endpoint.replace(/^\/+/, "");

    return this.http.get<T>(
      `${environment.apiBaseUrl}/${path}`
    );
  }
}

The generic type lets each caller describe the response it expects:

Example usagets
this.api.getApiRes<Product[]>("products");
this.api.getApiRes<User[]>("users");
this.api.getApiRes<Order[]>("orders");

5. Use the service from a component

src/app/products.component.tsts
import { Component, OnInit, inject } from "@angular/core";
import { ApiService } from "./services/api.service";

type Product = {
  id: number;
  name: string;
  price: number;
  inStock: boolean;
};

@Component({
  selector: "app-products",
  template: `
    <h1>Products</h1>

    @if (loading) {
      <p>Loading products...</p>
    }

    @if (error) {
      <p>{{ error }}</p>
    }

    <ul>
      @for (product of products; track product.id) {
        <li>
          <strong>{{ product.name }}</strong>
          — ${{ product.price }}
        </li>
      }
    </ul>
  `,
})
export class ProductsComponent implements OnInit {
  private readonly api = inject(ApiService);

  products: Product[] = [];
  loading = true;
  error = "";

  ngOnInit() {
    this.api.getApiRes<Product[]>("products").subscribe({
      next: (products) => {
        this.products = products;
        this.loading = false;
      },
      error: () => {
        this.error = "Could not load products.";
        this.loading = false;
      },
    });
  }
}

The component stays backend-agnostic

The component asks the API service for products. It does not need to know whether that service currently points to Forge API or your production backend.

6. Switch to production later

src/environments/environment.tsts
export const environment = {
  apiBaseUrl: "https://api.example.com",
};

Preserve the same endpoint paths and response contracts and the rest of your Angular application can stay unchanged.

Next steps

You can extend the same API service later with POST, PUT, PATCH and DELETE methods while keeping the backend location centralized.