Skip to content

HTTP Resource Plugin โ€‹

Generate Angular services using the httpResource API for automatic caching, state management, and reactive data loading.

Overview โ€‹

The HTTP Resource plugin extends ng-openapi to generate services that leverage Angular's new httpResource API instead of traditional HttpClient. This provides built-in caching, loading states, error handling, and reactive updates through Angular Signals.

Installation โ€‹

Install the plugin alongside ng-openapi:

bash
npm install ng-openapi @ng-openapi/http-resource --save-dev

Configuration โ€‹

Add the plugin to your OpenAPI configuration:

typescript
// openapi.config.ts
import { GeneratorConfig } from "ng-openapi";
import { HttpResourcePlugin } from "@ng-openapi/http-resource";

export default {
    input: "./swagger.json",
    output: "./src/api",
    clientName: "MyApi",
    plugins: [HttpResourcePlugin],
    options: {
        dateType: "Date",
        enumStyle: "enum",
    },
} as GeneratorConfig;

Generation โ€‹

Generate your API resources:

bash
ng-openapi -c openapi.config.ts

This creates both traditional services and HTTP resource services:

src/api/
โ”œโ”€โ”€ models/           # TypeScript interfaces
โ”œโ”€โ”€ services/         # Traditional HttpClient services
โ”œโ”€โ”€ resources/        # HTTP Resource services
โ”‚   โ”œโ”€โ”€ index.ts      # Resource exports
โ”‚   โ””โ”€โ”€ *.resource.ts # Generated resources
โ”œโ”€โ”€ providers.ts      # Provider functions
โ””โ”€โ”€ index.ts         # Main exports

Provider Setup โ€‹

Configure the provider in your application:

typescript
// app.config.ts
import { ApplicationConfig } from "@angular/core";
import { provideMyApiClient } from "./api/providers";

export const appConfig: ApplicationConfig = {
    providers: [
        provideMyApiClient({
            basePath: "https://api.example.com",
        }),
    ],
};

Basic Usage โ€‹

Inject and use the generated resources in your components:

typescript
import { Component, inject } from "@angular/core";
import { UsersResource } from "./api/resources";

@Component({
    selector: "app-users",
    template: `
        <div>
            @if (users.isLoading()) {
                <p>Loading users...</p>
            } @else if (users.error()) {
                <p>Error: {{ users.error()?.message }}</p>
            } @else {
                @for (user of users.value(); track user.id) {
                    <div>{{ user.name }}</div>
                }
            }
        </div>
    `,
})
export class UsersComponent {
    private readonly usersResource = inject(UsersResource);

    readonly users = this.usersResource.getUsers();
}

Dynamic Parameters โ€‹

Use Signals for reactive parameter binding:

typescript
export class UserDetailComponent {
    private readonly usersResource = inject(UsersResource);
    private readonly userId = signal(1);

    // Automatically refetches when userId changes
    readonly user = this.usersResource.getUserById(this.userId);

    updateUser(newId: number) {
        this.userId.set(newId); // Triggers automatic refetch
    }
}

Default Values โ€‹

Provide fallback values while data is loading:

typescript
export class UsersComponent {
    private readonly usersResource = inject(UsersResource);

    readonly users = this.usersResource.getUsers({ defaultValue: [] });
}

Query Parameters โ€‹

Pass both static and reactive query parameters:

typescript
export class SearchComponent {
    private readonly usersResource = inject(UsersResource);
    private readonly searchTerm = signal("");
    private readonly pageSize = signal(10);

    readonly searchResults = this.usersResource.searchUsers(
        this.searchTerm, // reactive search term
        this.pageSize, // reactive page size
        "active", // static status filter
    );

    updateSearch(term: string) {
        this.searchTerm.set(term);
    }
}

Resource vs Service Comparison โ€‹

FeatureHTTP ResourceTraditional Service
Loading Stateโœ… Built-in isLoading()โŒ Manual state management
Error Handlingโœ… Built-in error()โŒ Manual error handling
Reactivityโœ… Signal-basedโŒ Observable-based
Parameter Bindingโœ… Signal or staticโŒ Manual subscription
Request Deduplicationโœ… AutomaticโŒ Manual implementation
Maturityโœ… Stableโœ… Stable

Limitations โ€‹

Resources โ€‹

Released under the MIT License.
This site is powered by Netlify
About ยท Impressum