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:
https://apis.getforgeapi.com/YOUR_PROJECT_KEY/productsNeed your mock backend?
Create a Forge API endpoint and use it immediately from your Angular application.
Create your mock API2. Configure the API base URL
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
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
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:
this.api.getApiRes<Product[]>("products");
this.api.getApiRes<User[]>("users");
this.api.getApiRes<Order[]>("orders");5. Use the service from a component
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
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.