Normalize once
Move HTTP status, business codes, renamed fields, and custom errors into one typed response contract.
A framework-free HTTP response layer for axios, fetch, and ofetch. Configure business codes, hooks, and adapters once; expose Promise
Choose a backend response, run the repository's real createHttp, and compare the raw response with the final resolved value or rejected BizError.
createHttp()HTTP 200{
"status": 200,
"body": {
"code": 200,
"msg": "ok",
"data": {
"id": 42,
"name": "Ada"
}
}
}Ready to run// Run the scenario to inspect its resolved value or BizErrorconst instance = createAxiosInstance({ withCredentials: true });
const http = createHttp({
adapter: axiosAdapter(instance),
defaults: { baseURL: "/api", timeout: 15_000 },
envelope: { code: "code", msg: "msg", data: "data" },
hooks: { onRequest: auth(getToken), onResponseError: showError },
});Request hooks prepare the call, the adapter executes HTTP, and the selected response policy produces Promise<T>. Application state stays with the caller.
Auth, locale, business codes, query functions, downloads, and a migration path in one example.
02 / ProtocolModel the response contractHTTP-only defaults, explicit envelopes, renamed fields, custom errors, and expected failure bodies.
03 / TransportKeep adapters interchangeableUse native settings without leaking baseURL, query serialization, timeout, or error rules into each adapter.
A small project with two plain requests can keep native fetch or axios. envoi becomes useful when several endpoints or applications must agree on response extraction, business failures, shared headers, adapter behavior, and the value returned to callers.