Recipes¶
Bearer Refresh Single-Flight¶
Centralize token refresh, avoid multiple concurrent refreshes, and skip authentication endpoints so the client does not loop.
import { bearerAuth, bearerRefreshGuard, createHttpClient } from "@cedvict/http-guardian";
const api = createHttpClient({
baseUrl: "https://api.example.com",
auth: bearerAuth(() => tokenStore.access()),
parser,
guards: [
bearerRefreshGuard({
refreshFn: () => tokenStore.refresh(),
skipRefreshFor: (ctx) => ctx.url.includes("/auth/")
})
]
});
Cookie + CSRF + Safe Refresh¶
Recommended mode for a cookie-backed browser session.
import {
cookieAuth,
cookieSafeRefreshGuard,
createApiParserRestClassic,
createHttpClient,
csrfGuard
} from "@cedvict/http-guardian";
const api = createHttpClient({
baseUrl: "https://app.example.com/api",
auth: cookieAuth({ credentials: "include" }),
parser: createApiParserRestClassic(),
guards: [
csrfGuard({ headerName: "X-CSRF-TOKEN" }),
cookieSafeRefreshGuard({
refreshPath: "/auth/refresh",
mePath: "/auth/me"
})
]
});
Observable Client for Angular¶
import { createHttpClient, noAuth } from "@cedvict/http-guardian";
import { toObservableClient } from "@cedvict/http-guardian-rx";
const promiseClient = createHttpClient({ baseUrl, auth: noAuth(), parser });
const api$ = toObservableClient(promiseClient);
api$.get<User[]>("/users").subscribe((result) => {
if (result.ok) render(result.data);
});
Backend Trace to Logger, Sentry, and OTel¶
import { correlationIdGuard, createApiParserStructured } from "@cedvict/http-guardian";
import { loggerPlugin } from "@cedvict/http-guardian-plugin-logger";
import { sentryPlugin } from "@cedvict/http-guardian-plugin-sentry";
import { otelPlugin } from "@cedvict/http-guardian-plugin-otel";
const api = createHttpClient({
baseUrl,
auth,
parser: createApiParserStructured(),
guards: [correlationIdGuard(), traceMetaGuard],
plugins: [loggerPlugin({ label: "api" }), sentryPlugin(), otelPlugin()]
});