Getting Started
Quick Start
Get up and running with Spoosh in minutes
This guide will help you set up Spoosh and make your first type-safe API call.
Prerequisites
- Node.js 18+
- TypeScript 5.0+
- Angular 17+
Installation
npm install @spoosh/core @spoosh/angular @spoosh/plugin-cache @spoosh/plugin-deduplication @spoosh/plugin-invalidationDefine Your API Schema
Create a file to define your API types:
type User = {
id: number;
name: string;
email: string;
};
type CreateUserBody = {
name: string;
email: string;
};
export type ApiSchema = {
users: {
GET: { data: User[] };
POST: { data: User; body: CreateUserBody };
};
"users/:id": {
GET: { data: User };
PUT: { data: User; body: Partial<CreateUserBody> };
DELETE: void;
};
search: {
GET: { data: User[]; query: { q: string; page?: number } };
};
};Create the Client
Set up the Spoosh client with plugins:
import { Spoosh } from "@spoosh/core";
import { createAngularSpoosh } from "@spoosh/angular";
import { cachePlugin } from "@spoosh/plugin-cache";
import { deduplicationPlugin } from "@spoosh/plugin-deduplication";
import { invalidationPlugin } from "@spoosh/plugin-invalidation";
import type { ApiSchema } from "./schema";
const spoosh = new Spoosh<ApiSchema, Error>("/api").use([
cachePlugin({ staleTime: 5000 }),
deduplicationPlugin(), // Prevent duplicate requests during invalidation
invalidationPlugin(), // Auto-refresh queries after mutations
]);
export const { injectRead, injectWrite } = createAngularSpoosh(spoosh);Why these plugins?
invalidationPluginautomatically refreshes related queries after mutationsdeduplicationPluginprevents duplicate network requests when multiple queries invalidate at once
Use in Components
Now you can use the inject functions in your components:
import { Component } from "@angular/core";
import { injectRead } from "../api/client";
@Component({
selector: "app-user-list",
template: `
@if (query.loading()) {
<div>Loading...</div>
} @else if (query.error()) {
<div>Error: {{ query.error()!.message }}</div>
} @else {
<div>
<button (click)="query.refetch()">Refresh</button>
<ul>
@for (user of query.data(); track user.id) {
<li>{{ user.name }}</li>
}
</ul>
</div>
}
`,
})
export class UserListComponent {
query = injectRead((api) => api("users").GET());
}