Request & Response Helpers
Content type handling, response conversion, and request body processing
CallApi automatically handles content types and response parsing, with utilities for common data formats.
Automatic Content-Type Detection and Assignment
Request bodies are automatically assigned the correct Content-Type header:
- Objects →
application/json - Query strings →
application/x-www-form-urlencoded - FormData →
multipart/form-data(browser handled)
import { callApi } from "@zayne-labs/callapi";
// Automatically sets Content-Type: application/json
await callApi("/api/users", {
method: "POST",
body: { name: "John", age: 30 },
});
// Automatically sets Content-Type: application/x-www-form-urlencoded
await callApi("/api/form", {
method: "POST",
body: "name=John&age=30",
});
// Override when needed
await callApi("/api/custom", {
method: "POST",
body: data,
headers: { "Content-Type": "application/custom+json" },
});Smart Response Parsing
Responses are automatically parsed based on their Content-Type header:
- JSON types (
application/json,application/vnd.api+json) → Parsed as JSON - Text types (
text/*,application/xml) → Parsed as text - Everything else → Parsed as blob
import { callApi } from "@zayne-labs/callapi";
// Automatically parsed based on Content-Type response header
const { data: user } = await callApi("/api/user"); // JSON
const { data: html } = await callApi("/page.html"); // Text
const { data: image } = await callApi("/avatar.png"); // BlobManual Response Type Override
You can still manually specify the response type if needed:
Available response types include:
- All response types from the Fetch API:
json()(default fallback)text()blob()arrayBuffer()formData()
stream- Returns the directReadableStream
import { callApi } from "@zayne-labs/callapi";
const { data: imageBlob } = await callApi("/image", {
responseType: "blob",
});
const { data: rawText } = await callApi("/data.json", {
responseType: "text", // Get JSON as raw text
});
const { data: buffer } = await callApi("/binary", {
responseType: "arrayBuffer",
});
const { data: stream } = await callApi("/large-file", {
responseType: "stream", // ReadableStream for progressive processing
});Custom Response Parser
Use a custom parser function:
import { callApi } from "@zayne-labs/callapi";
const { data } = await callApi("/api/data", {
responseParser: (responseString) => customParser(responseString),
});Result Modes
The resultMode option dictates how CallApi processes and returns the final result:
- "all" (default): Returns
{ data, error, response }. Standard lifecycle. - "onlyData": Returns only the data from the response.
- "onlyResponse": Returns only the
Responseobject. - "fetchApi": Also returns only the
Responseobject, but also skips parsing of the response body internally and data/errorData schema validation. - "withoutResponse": Returns
{ data, error }. Standard lifecycle, but omits theresponseproperty.
The fetchApi Mode
The fetchApi mode is designed for scenarios where you want most of the library's benefits (URL resolution, plugins, hooks) don't want any internal parsing of the response body to occur, just like the Fetch Api.
When set to fetchApi:
- No Parsing: The library will not attempt to read or parse the response body.
- No Validation: Both data error-data validation are skipped.
By default, simplified modes ("onlyData", "onlyResponse", "fetchApi") do not throw errors.
Success/failure should be handled via hooks or by checking the return value (e.g., if (data) or if (response?.ok)).
To force an exception, set throwOnError: true.
Request Body Utilities
Object Bodies
Objects are automatically JSON stringified:
import { callApi } from "@zayne-labs/callapi";
// CallApi handles this automatically
await callApi("/api/user", {
method: "POST",
body: { name: "John", age: 30 },
});
// Equivalent to manual fetch:
// fetch("/api/user", {
// method: "POST",
// headers: { "Content-Type": "application/json" },
// body: JSON.stringify({ name: "John", age: 30 }),
// });Custom Body Serializer
Override the default JSON serialization:
import { callApi } from "@zayne-labs/callapi";
await callApi("/api/data", {
method: "POST",
body: { name: "John", age: 30 },
bodySerializer: (body) => customSerialize(body),
});Query String Bodies
Convert objects to URL-encoded strings:
import { callApi } from "@zayne-labs/callapi";
import { toQueryString } from "@zayne-labs/callapi/utils";
await callApi("/api/search", {
method: "POST",
body: toQueryString({ name: "John", age: 30 }),
});
// Body: "name=John&age=30"
// Content-Type: application/x-www-form-urlencodedFormData Bodies
Convert objects to FormData with intelligent type handling:
import { callApi } from "@zayne-labs/callapi";
import { toFormData } from "@zayne-labs/callapi/utils";
await callApi("/api/upload", {
method: "POST",
body: toFormData({
avatar: imageFile, // Files/blobs added directly
tags: ["dev", "designer"], // Arrays become multiple entries
metadata: { role: "admin" }, // Objects are JSON stringified
name: "John", // Primitives added as-is
}),
});How toFormData handles different types:
- Files/Blobs → Added directly
- Arrays → Multiple entries with same key
- Objects → JSON stringified
- Primitives → Added as-is
Last updated on