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:

  • Objectsapplication/json
  • Query stringsapplication/x-www-form-urlencoded
  • FormDatamultipart/form-data (browser handled)
content-types.ts
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
response-parsing.ts
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"); // Blob

Manual 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 direct ReadableStream
api.ts
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:

custom-parser.ts
import { callApi } from "@zayne-labs/callapi";

const { data } = await callApi("/api/data", {
	responseParser: (responseString) => customParser(responseString),
});

Request Body Utilities

Object Bodies

Objects are automatically JSON stringified:

object-bodies.ts
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:

custom-serializer.ts
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:

query-string-bodies.ts
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-urlencoded

FormData Bodies

Convert objects to FormData with intelligent type handling:

formdata-bodies.ts
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
Edit on GitHub

Last updated on

On this page