@simplix-react/api
v0.2.2
Published
Orval mutator singleton for simplix-react domain packages
Downloads
242
Readme
@simplix-react/api
Orval mutator singleton for simplix-react domain packages. Provides a centralized HTTP client registry, a typed HttpError class, and error classification utilities for consistent error handling across generated domain packages.
Installation
pnpm add @simplix-react/apiNote: Domain packages generated by
simplix openapiinclude this dependency automatically.
API Overview
| Export | Kind | Description |
| --- | --- | --- |
| configureMutator | Function | Register an OrvalMutator fetch function (default or named strategy) |
| getMutator | Function | Retrieve a registered mutator by strategy name |
| setRequestLocale | Function | Set locale for automatic Accept-Language header injection |
| getRequestLocale | Function | Get the currently configured request locale |
| HttpError | Class | Typed HTTP error with status, message, and optional data |
| getValidationErrors | Function | Extract validation field errors from any error shape |
| getErrorMessage | Function | Extract a human-readable message from any error |
| getErrorCode | Function | Extract an application error code from any error |
| getHttpStatus | Function | Extract HTTP status code from any error |
| classifyError | Function | Classify an error into a category (ServerErrorEvent) |
| createMutationErrorHandler | Function | Create a React Query onError handler with per-category callbacks |
Type Exports
| Export | Description |
| --- | --- |
| OrvalMutator | Mutator function signature: (url: string, options?: RequestInit) => Promise<T> |
| ErrorType | Orval error type alias: Error & { data?: T } |
| BodyType | Orval body type alias: T |
| ValidationFieldError | Field-level validation error (field, message) |
| ErrorCategory | Error category union: "validation" \| "auth" \| "client" \| "server" \| "network" \| "unknown" |
| ServerErrorEvent | Classified error event with category, status, errorCode, message, and validationErrors |
Key Concepts
HttpError
A typed error class for HTTP responses with non-2xx status codes. Carries the HTTP status, error message, and optional response data.
import { HttpError } from "@simplix-react/api";
async function fetchJson<T>(url: string, options?: RequestInit): Promise<T> {
const res = await fetch(url, options);
if (!res.ok) {
const data = await res.json().catch(() => undefined);
throw new HttpError(res.status, res.statusText, data);
}
return res.json() as Promise<T>;
}configureMutator / getMutator
A global registry for Orval mutator functions. Domain packages call getMutator() in their generated client code. The application configures the mutator once at startup.
import { configureMutator, getMutator } from "@simplix-react/api";
// Register the default mutator
configureMutator(async (url, options) => {
const res = await fetch(url, options);
if (!res.ok) throw new HttpError(res.status, res.statusText);
return res.json();
});
// Register a named strategy (for multi-backend setups)
configureMutator("admin-api", async (url, options) => {
const res = await fetch(`/admin${url}`, options);
if (!res.ok) throw new HttpError(res.status, res.statusText);
return res.json();
});
// Retrieve (used internally by generated code)
const mutator = getMutator(); // default strategy
const adminMutator = getMutator("admin-api"); // named strategyRequest Locale (Accept-Language Header)
When a locale is configured via setRequestLocale, getMutator automatically injects an Accept-Language header into every outgoing request. This ensures the server receives the application's selected language rather than the browser's OS-level language preference.
import { setRequestLocale, getRequestLocale } from "@simplix-react/api";
// Set the locale (typically wired to i18n adapter)
setRequestLocale("en");
// All subsequent API requests include: Accept-Language: en
const mutator = getMutator();
await mutator("/api/pets"); // → Accept-Language: en
// Check current locale
getRequestLocale(); // "en"How It Works
setRequestLocale(locale)stores the locale in a module-scoped variable (tab-local, not shared across tabs)getMutator()returns a wrapper that mergesAccept-Languageinto the request headers as a plain object- If the caller already sets an explicit
Accept-Languageheader, it is not overwritten - If no locale is configured,
getMutator()returns the raw mutator without modification
Why This Is Needed
Browsers set the Accept-Language header automatically on all HTTP requests, but the value reflects OS/browser language settings, not the application's i18n selection. For example, a user with a Korean OS who selects English in the app would still send Accept-Language: ko without this feature. setRequestLocale ensures the server receives the correct language.
Integration with @simplix-react/i18n
Wire the i18n adapter's locale changes to setRequestLocale in the app's i18n config:
import { setRequestLocale } from "@simplix-react/api";
import { createI18nConfig } from "@simplix-react/i18n";
export const { adapter: i18nAdapter, i18nReady } = createI18nConfig({ ... });
// Sync locale changes to API request headers
i18nAdapter.onLocaleChange(setRequestLocale);
i18nReady.then(() => setRequestLocale(i18nAdapter.locale));After this setup, every API request automatically includes Accept-Language matching the app's active locale. When the user switches language, subsequent requests reflect the new locale immediately.
Note:
@simplix-react/apiand@simplix-react/i18nhave no direct dependency on each other. The wiring happens at the application level, keeping both packages decoupled.
Error Utilities
A set of duck-typing utilities that extract structured information from any error shape. They work with HttpError, Orval's ApiError, Spring Boot error responses, Rails-style errors, and plain objects.
getValidationErrors
Extracts field-level validation errors from any error. Supports multiple shapes:
{ errorDetail: [{ field, message }] }(Spring Boot / ApiResponseError){ errors: [{ field, message }] }(plain array){ errors: { [field]: string[] } }(Rails-style)HttpError.datacontaining any of the aboveJSON.parse(error.body)fallback
import { getValidationErrors } from "@simplix-react/api";
const errors = getValidationErrors(error);
if (errors) {
errors.forEach(({ field, message }) => {
form.setFieldError(field, message);
});
}getErrorMessage / getErrorCode / getHttpStatus
import { getErrorMessage, getErrorCode, getHttpStatus } from "@simplix-react/api";
const message = getErrorMessage(error); // "Not Found" or "An unknown error occurred"
const code = getErrorCode(error); // "USER_NOT_FOUND" or null
const status = getHttpStatus(error); // 404 or nullclassifyError
Classifies any error into a ServerErrorEvent with a category:
| Category | Condition |
| --- | --- |
| network | TypeError with no HTTP status |
| auth | Status 401 or 403 |
| server | Status >= 500 |
| validation | Status 400-499 with validation errors |
| client | Status 400-499 without validation errors |
| unknown | Everything else |
import { classifyError } from "@simplix-react/api";
const event = classifyError(error);
// event.category → "validation"
// event.status → 422
// event.message → "Validation failed"
// event.validationErrors → [{ field: "email", message: "is required" }]createMutationErrorHandler
Creates a React Query onError callback with per-category handlers. Useful with useMutation's onError option.
import { createMutationErrorHandler } from "@simplix-react/api";
const onError = createMutationErrorHandler({
onValidationError: (event) => {
event.validationErrors?.forEach(({ field, message }) => {
form.setFieldError(field, message);
});
},
onAuthError: () => {
redirect("/login");
},
onServerError: (event) => {
toast.error(event.message);
},
onNetworkError: () => {
toast.error("Network error. Please check your connection.");
},
onUnknownError: (event) => {
toast.error(event.message);
},
});
// Use with React Query
useMutation({
mutationFn: createUser,
onError,
});Related Packages
| Package | Description |
| --- | --- |
| @simplix-react/contract | Zod-based type-safe API contract definitions |
| @simplix-react/react | React Query hooks derived from contracts |
| @simplix-react/auth | Authentication middleware (Bearer, API Key, OAuth2) |
Next Step -> @simplix-react/auth
