Skip to content

Foundatio FetchClientTyped, ergonomic fetch for JS/TS

JSON helpers, caching, middleware, rate limiting, circuit breaker, and great DX

Foundatio

Quick Example

FetchClient works multiple ways - pick whichever style you prefer:

ts
import fc from "@foundatiofx/fetchclient";

// GET with typed JSON response
const { data: user } = await fc.getJSON<User>("/api/users/1");

// POST with body
const { data: created } = await fc.postJSON<User>("/users", { name: "Alice" });

// Full response access
const response = await fc.getJSON<User[]>("/users");
console.log(response.status, response.ok, response.data);

Functional API

ts
import { getJSON, postJSON, setBaseUrl } from "@foundatiofx/fetchclient";

setBaseUrl("https://api.example.com");

const { data: users } = await getJSON<User[]>("/users");
const { data: created } = await postJSON<User>("/users", { name: "Alice" });

Class-Based API

ts
import { FetchClient } from "@foundatiofx/fetchclient";

const client = new FetchClient({ baseUrl: "https://api.example.com" });

const { data: user } = await client.getJSON<User>("/users/1");
const { data: created } = await client.postJSON<User>("/users", { name: "Alice" });

Caching

ts
const { data } = await getJSON<User>("/api/users/1", {
  cacheKey: ["users", "1"],
  cacheDuration: 60000,
  cacheTags: ["users"],
});

// Invalidate all user cache entries
getCache().deleteByTag("users");

Middleware

ts
import fc from "@foundatiofx/fetchclient";

// Built-in middleware factories
fc.use(fc.middleware.retry({ limit: 3 }));
fc.use(fc.middleware.rateLimit({ maxRequests: 100, windowSeconds: 60 }));
fc.use(fc.middleware.circuitBreaker({ failureThreshold: 5 }));

// Custom middleware
fc.use(async (ctx, next) => {
  console.log("Request:", ctx.request.url);
  await next();
  console.log("Response:", ctx.response?.status);
});

Testing

ts
import { MockRegistry } from "@foundatiofx/fetchclient/mocks";

const mocks = new MockRegistry();
mocks.onGet("/api/users").reply(200, [{ id: 1, name: "Alice" }]);
mocks.install(provider);

// Requests are mocked - no network calls
const { data } = await getJSON("/api/users");

Released under the MIT License.