Skip to main content

FetchRequest

A class representing a typed fetch request, which inherits from the native Request.

On top of the properties available in native requests, FetchRequest instances have their URL automatically prefixed with the base URL of their fetch instance. Default options are also applied, if present in the fetch instance.

The path of the request is extracted from the URL, excluding the base URL, and is available in the path property.

constructor()

Creates a new FetchRequest instance.

new FetchRequest<Schema, Method, Path>(fetch, input);
new FetchRequest<Schema, Method, Path>(fetch, input, init);

Arguments:

  1. fetch: Fetch

    The fetch instance used as the source of defaults (such as baseURL, headers, and other request options).

  2. input: FetchInput<Schema, Method, Path>

    The request input. It can be a path string (e.g. '/users'), a URL, or another FetchRequest instance.

  3. init: FetchRequestInit | undefined

    Optional request options. If provided, they override the defaults from fetch.

Type arguments:

  1. Schema: HttpSchema

    The HTTP schema used for the fetch instance.

  2. Method: string

    The HTTP method of the request. Must be one of the methods of the path defined in the schema.

  3. Path: string

    The path of the request. Must be one of the paths defined in the schema.

import { HttpSchema } from '@zimic/http';
import { createFetch, FetchRequest } from '@zimic/fetch';

interface User {
id: string;
username: string;
}

type Schema = HttpSchema<{
'/users': {
POST: {
request: {
headers: { 'content-type': 'application/json' };
body: { username: string };
};
response: {
201: { body: User };
};
};
};
}>;

const fetch = createFetch<Schema>({
baseURL: 'http://localhost:3000',
});

const request = new FetchRequest(fetch, '/users', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ username: 'me' }),
});

Related:

request.path

The path of the request, excluding the base URL.

Type: string

const request = new fetch.Request('/users', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ username: 'me' }),
});

console.log(request.path); // '/users'

request.method

The HTTP method of the request.

Type: HttpMethod

const request = new fetch.Request('/users', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ username: 'me' }),
});

console.log(request.method); // 'POST'

request.toObject()

Converts the request into a plain object. This method is useful for serialization, debugging, and logging purposes.

request.toObject();
request.toObject(options);

Arguments:

  1. options: FetchRequestObjectOptions | undefined

    The options for converting the request. By default, the body of the request will not be included.

    • includeBody: boolean | undefined (default false)

      Whether to include the body of the request.

Returns: FetchRequestObject

A plain object representing this request. If options.includeBody is true, the body will be included and the return is a Promise. Otherwise, the return is the plain object itself without the body.

const request = new fetch.Request('/users', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ username: 'me' }),
});

const requestObject = request.toObject();
console.log(requestObject);
// { url: '...', path: '/users', method: 'POST', ... }

const requestObjectWithBody = await request.toObject({ includeBody: true });
console.log(requestObjectWithBody);
// { url: '...', path: '/users', method: 'POST', body: { username: 'me' }, ... }

If included, the body is parsed automatically based on the content-type header of the request.

content-typeParsed as
application/jsonJSON (object)
application/xmlstring
application/x-www-form-urlencodedHttpSearchParams
application/* (others)Blob
multipart/form-dataHttpFormData
multipart/* (others)Blob
text/*string
image/*Blob
audio/*Blob
font/*Blob
video/*Blob
*/* (others)JSON (object) if possible, otherwise Blob
NOTE: Already used body

If the body of the request has already been used (e.g., read with request.json()), it will not be included in the plain object, even if options.includeBody is true. This will be flagged with a warning in the console.

If you access the body before calling request.toObject(), consider reading it from a cloned request with request.clone().

const request = new fetch.Request('/users', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ username: 'me' }),
});

// Reading the body from a cloned request:
const requestBody = await request.clone().json();
console.log(requestBody);

const requestObject = await request.toObject({ includeBody: true });
console.log(requestObject);

Alternatively, you can disable the warning by including the body conditionally based on request.bodyUsed.

// Include the body only if available:
const requestObject = await request.toObject({
includeBody: !request.bodyUsed,
});