HTTP service

@sometic/http provides createHttp: a fetch-first client with interceptors, retry, dedupe, typed errors, and optional auth refresh via @sometic/http/auth.

This page is the services-hub summary. Full guide: HTTP utility.

Overview

PieceRole
createHttpBuild a disposable client
InterceptorsRequest / response / error hooks
@sometic/http/authOptional Sometic auth refresh queue
createMockFetcherDeterministic tests

When to use

  • Browser or SSR apps that want a thin fetch wrapper with typed errors
  • Coordinating 401 recovery with @sometic/auth without embedding provider SDKs
  • Injecting a custom fetcher for Node, edge, or mocks

When not to use

  • You already standardize on another HTTP stack and only need auth session APIs
  • GraphQL clients with their own link chains (compose carefully; do not assume this replaces them)
  • Treating client HTTP status handling as server authorization

Installation

pnpm
pnpm add @sometic/http
npm
npm install @sometic/http
yarn
yarn add @sometic/http
bun
bun add @sometic/http

Optional peer for auth interceptors: @sometic/auth.

Usage

ts
import { createHttp } from "@sometic/http";
import { createAuthInterceptor } from "@sometic/http/auth";

const http = createHttp({
    baseUrl: "https://api.example.com",
    timeoutMs: 15_000,
    interceptors: [createAuthInterceptor({ auth })],
});

const { data, status } = await http.get<Profile>("/me");
const created = await http.post("/items", JSON.stringify(body), {
    headers: { "Content-Type": "application/json" },
});

http.dispose();

Key APIs

ts
createHttp(options?: CreateHttpOptions): HttpClient
OptionRole
baseUrlPrefix for relative URLs
headersDefault headers
fetcherInjectable fetch (SSR / mocks)
timeoutMsDefault timeout
interceptorsRequest / response / error hooks
retryBackoff policy or false
dedupeIn-flight dedupe or false

Client methods: request, get, post, put, patch, delete, extend, dispose.

Auth refresh queue

On unauthorized responses, createAuthInterceptor:

  1. Joins a single refresh flight via auth.handleUnauthorized()
  2. Replays the request once (meta.authRetried)
  3. Surfaces HTTP_UNAUTHORIZED if the session is not restored

Auth core never imports HTTP. Provider SDKs stay in auth adapters. See Interceptors.

Errors

CodeMeaning
HTTP_NETWORKNetwork failure
HTTP_TIMEOUTTimeout
HTTP_ABORTEDAborted
HTTP_STATUSNon-OK status
HTTP_PARSEBody parse failure
HTTP_UNAUTHORIZEDAuth recovery failed
HTTP_DISPOSEDUsed after dispose

How it works

createHttp wraps an injectable fetcher (defaulting to platform fetch when present). Interceptors form a pipeline around request execution. Retry and dedupe are opt-in policies on the client, not global singletons. extend derives a child client with merged defaults; dispose cancels in-flight bookkeeping the client owns.

Security

Do not log tokens. Prefer credentialed fetcher wrappers for cookie sessions. SSR must pass an explicit fetcher. Client HTTP does not replace server authorization.

Edge cases

EdgeBehavior
Call after disposeHTTP_DISPOSED
Parallel 401s with auth interceptorOne refresh flight; single replay
Relative URL without baseUrlPassed through to fetcher as-is
Custom parse failuresHTTP_PARSE

FAQ

Is auth required to use HTTP?

No. Import @sometic/http/auth only when wiring Sometic auth.

How do I mock?

createMockFetcher(handlers) or inject a custom fetcher.

Does this bundle Axios?

No. Fetch-first by design.

Where is the longer guide?

HTTP utility under Utilities.

SSR?

Pass fetcher explicitly. Do not assume globalThis.fetch exists at import time in every runtime.