← All @molecule/* packages · App templates

@molecule/api-http

Core interface · http · API (Node) · v1.0.1 · Apache-2.0

HTTP client interface

npm install @molecule/api-http

npm · Source on GitHub

How it works

@molecule/api-http is the http core interface on the API (Node) side: the API your app calls, with no vendor inside.

Choose the implementation by bonding one of its 2 providers: @molecule/api-http-axios, @molecule/api-http-fetch.

import { get, post } from '@molecule/api-http'
import type { HttpError } from '@molecule/api-http'

try {
  const res = await get<{ id: string }>('https://api.example.com/items/1', {
    headers: { Authorization: `Bearer ${apiToken}` },
    params: { expand: 'owner' },
    timeout: 5000,
  })
  use(res.data) // body is on `.data`, already JSON-parsed
} catch (error) {
  const status = (error as HttpError).response?.status // 404, 500, … — errors THROW
}

Providers (2): @molecule/api-http-axios, @molecule/api-http-fetch

Works with: @molecule/api-bond

Reference

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

HTTP client core interface for molecule.dev — outbound server-to-server requests.

Defines the HttpClient contract plus convenience functions (request, get, post, put, patch, del) that delegate to the bonded client. Works with ZERO wiring: when no bond is configured, a built-in fetch-based client is used. Bond @molecule/api-http-axios (or another client) only when you need its extras (interceptors, per-instance defaults via create).

Quick Start

import { get, post } from '@molecule/api-http'
import type { HttpError } from '@molecule/api-http'

try {
  const res = await get<{ id: string }>('https://api.example.com/items/1', {
    headers: { Authorization: `Bearer ${apiToken}` },
    params: { expand: 'owner' },
    timeout: 5000,
  })
  use(res.data) // body is on `.data`, already JSON-parsed
} catch (error) {
  const status = (error as HttpError).response?.status // 404, 500, … — errors THROW
}

Type

core

Installation

npm install @molecule/api-http @molecule/api-bond

API

Interfaces

HttpClient

HTTP client interface that all HTTP bond packages must implement.

Provides methods for each HTTP verb plus optional interceptors and client factory support.

interface HttpClient {
  /**
   * Makes an HTTP request.
   */
  request<T = unknown>(url: string, options?: HttpRequestOptions): Promise<HttpResponse<T>>

  /**
   * Makes a GET request.
   */
  get<T = unknown>(
    url: string,
    options?: Omit<HttpRequestOptions, 'method' | 'body'>,
  ): Promise<HttpResponse<T>>

  /**
   * Makes a POST request.
   */
  post<T = unknown>(
    url: string,
    body?: unknown,
    options?: Omit<HttpRequestOptions, 'method' | 'body'>,
  ): Promise<HttpResponse<T>>

  /**
   * Makes a PUT request.
   */
  put<T = unknown>(
    url: string,
    body?: unknown,
    options?: Omit<HttpRequestOptions, 'method' | 'body'>,
  ): Promise<HttpResponse<T>>

  /**
   * Makes a PATCH request.
   */
  patch<T = unknown>(
    url: string,
    body?: unknown,
    options?: Omit<HttpRequestOptions, 'method' | 'body'>,
  ): Promise<HttpResponse<T>>

  /**
   * Makes a DELETE request.
   */
  delete<T = unknown>(
    url: string,
    options?: Omit<HttpRequestOptions, 'method'>,
  ): Promise<HttpResponse<T>>

  /**
   * Creates a new client with the given defaults.
   */
  create?(defaults: HttpRequestOptions): HttpClient

  /**
   * Adds a request interceptor.
   */
  addRequestInterceptor?(interceptor: RequestInterceptor): () => void

  /**
   * Adds a response interceptor.
   */
  addResponseInterceptor?(interceptor: ResponseInterceptor): () => void

  /**
   * Adds an error interceptor.
   */
  addErrorInterceptor?(interceptor: ErrorInterceptor): () => void
}

HttpError

HTTP error.

interface HttpError extends Error {
  /**
   * Response (if available).
   */
  response?: HttpResponse

  /**
   * Request options.
   */
  request: HttpRequestOptions & { url: string }

  /**
   * Error code (e.g., 'ECONNREFUSED', 'ETIMEDOUT').
   */
  code?: string

  /**
   * Whether the request was aborted.
   */
  isAborted?: boolean

  /**
   * Whether the request timed out.
   */
  isTimeout?: boolean
}

HttpRequestOptions

HTTP request options.

interface HttpRequestOptions {
  /**
   * HTTP method.
   */
  method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'

  /**
   * Request headers.
   */
  headers?: Record<string, string>

  /**
   * Request body (will be JSON-stringified if object).
   */
  body?: unknown

  /**
   * Query parameters.
   */
  params?: Record<string, string | number | boolean | undefined>

  /**
   * Request timeout in milliseconds.
   */
  timeout?: number

  /**
   * Base URL to prepend to the request URL.
   */
  baseURL?: string

  /**
   * Whether to include credentials (cookies) in the request.
   */
  credentials?: 'omit' | 'same-origin' | 'include'

  /**
   * Response type.
   */
  responseType?: 'json' | 'text' | 'blob' | 'arraybuffer'

  /**
   * Signal for aborting the request.
   */
  signal?: AbortSignal

  /**
   * Custom options passed to the underlying client.
   */
  [key: string]: unknown
}

HttpResponse

HTTP response.

interface HttpResponse<T = unknown> {
  /**
   * Response status code.
   */
  status: number

  /**
   * Response status text.
   */
  statusText: string

  /**
   * Response headers.
   */
  headers: Record<string, string>

  /**
   * Response body.
   */
  data: T

  /**
   * Original request options.
   */
  request: HttpRequestOptions & { url: string }
}

Types

ErrorInterceptor

Callback invoked when an HTTP request fails, allowing error transformation or logging before re-throwing.

type ErrorInterceptor = (error: HttpError) => HttpError | Promise<HttpError>

RequestInterceptor

Function that transforms an outgoing HTTP request before it is sent (e.g. add auth headers).

type RequestInterceptor = (
  options: HttpRequestOptions & { url: string },
) => (HttpRequestOptions & { url: string }) | Promise<HttpRequestOptions & { url: string }>

ResponseInterceptor

Function that transforms an incoming HTTP response before it is returned (e.g. unwrap data).

type ResponseInterceptor<T = unknown> = (
  response: HttpResponse<T>,
) => HttpResponse<T> | Promise<HttpResponse<T>>

Functions

del(url, options)

Sends an HTTP DELETE request using the bonded (or default) client.

function del(url: string, options?: Omit<HttpRequestOptions, 'method'>): Promise<HttpResponse<T>>
  • url — The request URL.
  • options — Request options (method is excluded).

Returns: The HTTP response containing status, headers, and parsed body data.

get(url, options)

Sends an HTTP GET request using the bonded (or default) client.

function get(
  url: string,
  options?: Omit<HttpRequestOptions, 'method' | 'body'>,
): Promise<HttpResponse<T>>
  • url — The request URL.
  • options — Request options (method and body are excluded).

Returns: The HTTP response containing status, headers, and parsed body data.

getClient()

Retrieves the bonded HTTP client. Falls back to the built-in fetch-based client if no bond has been configured.

function getClient(): HttpClient

Returns: The bonded HTTP client, or the default fetch-based client.

hasClient()

Checks whether a custom HTTP client is currently bonded.

function hasClient(): boolean

Returns: true if a custom HTTP client is bonded.

patch(url, body, options)

Sends an HTTP PATCH request using the bonded (or default) client.

function patch(
  url: string,
  body?: unknown,
  options?: Omit<HttpRequestOptions, 'method' | 'body'>,
): Promise<HttpResponse<T>>
  • url — The request URL.
  • body — The request body (objects are JSON-stringified automatically).
  • options — Request options (method and body are excluded).

Returns: The HTTP response containing status, headers, and parsed body data.

post(url, body, options)

Sends an HTTP POST request using the bonded (or default) client.

function post(
  url: string,
  body?: unknown,
  options?: Omit<HttpRequestOptions, 'method' | 'body'>,
): Promise<HttpResponse<T>>
  • url — The request URL.
  • body — The request body (objects are JSON-stringified automatically).
  • options — Request options (method and body are excluded).

Returns: The HTTP response containing status, headers, and parsed body data.

put(url, body, options)

Sends an HTTP PUT request using the bonded (or default) client.

function put(
  url: string,
  body?: unknown,
  options?: Omit<HttpRequestOptions, 'method' | 'body'>,
): Promise<HttpResponse<T>>
  • url — The request URL.
  • body — The request body (objects are JSON-stringified automatically).
  • options — Request options (method and body are excluded).

Returns: The HTTP response containing status, headers, and parsed body data.

request(url, options)

Sends an HTTP request using the bonded (or default) client.

function request(url: string, options?: HttpRequestOptions): Promise<HttpResponse<T>>
  • url — The request URL.
  • options — Request options including method, headers, body, and query params.

Returns: The HTTP response containing status, headers, and parsed body data.

setClient(client)

Registers an HTTP client as the active singleton. Called by bond packages during application startup.

function setClient(client: HttpClient): void
  • client — The HTTP client implementation to bond.

Available Providers

ProviderPackage
Axios@molecule/api-http-axios
Fetch@molecule/api-http-fetch

Injection Notes

Requirements

Peer dependencies:

  • @molecule/api-bond ^1.0.1

Runtime Dependencies

  • @molecule/api-bond

  • Non-2xx responses THROW an HttpError — they are not returned. Checking res.status for error codes after an await is dead code; catch and read error.response?.status / error.response?.data. Timeouts and aborts also throw (isTimeout / isAborted flags).

  • This category wires via setClient/getClient/hasClient (bond type http-client), not setProvider. The DELETE convenience function is del (delete is reserved); the HttpClient interface method is delete.

  • Object request bodies are JSON-stringified with Content-Type: application/json automatically. Response bodies are JSON-parsed onto res.data; a non-JSON body falls back to null — pass responseType: 'text' to get raw text.

  • create() and the interceptor methods are OPTIONAL client capabilities the built-in fetch client does NOT implement — bond a client that supports them (e.g. @molecule/api-http-axios) before calling getClient().addRequestInterceptor(...).

  • Outbound calls only: never fetch a raw user-supplied URL without validation (SSRF), and keep upstream API tokens in config/secrets — never in app code.