fetch
The result of createFetch
is a fetch instance typed with an HTTP schema,
mostly compatible with the native Fetch API.
Requests sent by the fetch instance have their URL automatically prefixed with the base URL of the instance. Default options are also applied to the requests, if provided.
fetch(input);
fetch(input, init);
Arguments:
-
input:
string | URL | FetchRequest
The resource to fetch, either a path, a URL, or another
FetchRequest
request. If a path is provided, it is automatically prefixed with the base URL of the fetch instance when the request is sent. If a URL or a request is provided, it is used as is. -
init:
FetchRequestInit
The options to use for the request. If a path or a URL is provided as the first argument, this argument is required and should contain at least the method of the request. If the first argument is a
FetchRequest
, this argument is optional. The options inherit from the nativeRequestInit
interface, with the following additional properties:-
method:
string
The HTTP method to use for the request. Differently from the native Fetch API, this is required to ensure that requests are typed correctly.
-
baseURL:
string | undefined
The base URL for the request. If provided, it will have preference over the default base URL of the fetch instance.
-
searchParams:
HttpSearchParamsSchema.Loose | undefined
The search parameters to be sent with the request. If provided, it will have preference over the default search parameters of the fetch instance.
-
Returns: Promise<FetchResponse>
A promise that resolves to a FetchResponse
, which is typed with the
schema of the fetch instance.
import { HttpSchema } from '@zimic/http';
import { createFetch } from '@zimic/fetch';
interface User {
id: string;
username: string;
}
type Schema = HttpSchema<{
'/users': {
GET: {
request: {
searchParams: { query?: string };
};
response: {
200: { body: User[] };
404: { body: { message: string } };
500: { body: { message: string } };
};
};
};
}>;
const fetch = createFetch<Schema>({
baseURL: 'http://localhost:3000',
headers: { 'accept-language': 'en' },
});
const response = await fetch('/users', {
method: 'GET',
searchParams: { query: 'u' },
});
if (response.status === 404) {
return null; // User not found
}
if (!response.ok) {
throw response.error;
}
const users = await response.json();
return users; // User[]
fetch.defaults
The default options for each request sent by the fetch instance.
Type: FetchDefaults
fetch.defaults
inherits from the native RequestInit
interface, with the following additional properties:
-
baseURL:
string | undefined
The base URL for the fetch instance, which will be prepended to all request URLs.
-
searchParams:
HttpSearchParamsSchema.Loose | undefined
The default search parameters to be sent with each request.
import { HttpSchema } from '@zimic/http';
import { createFetch } from '@zimic/fetch';
interface Post {
id: string;
title: string;
}
type Schema = HttpSchema<{
'/posts': {
POST: {
request: {
headers: { authorization?: string };
body: { title: string };
};
response: {
201: { body: Post };
};
};
};
}>;
const fetch = createFetch<Schema>({
baseURL: 'http://localhost:3000',
headers: { 'accept-language': 'en' },
});
fetch.defaults.headers.authorization = `Bearer ${accessToken}`;
Related:
fetch.onRequest
A listener function that is called before sending each request.
Type: (request: FetchRequest.Loose) => Promise<Request> | Request
Arguments:
-
request:
FetchRequest.Loose
The request to be sent.
Returns: Promise<Request> | Request
The request to use, either a modified version of the original request or a new one.
import { createFetch } from '@zimic/fetch';
import { HttpSchema } from '@zimic/http';
interface User {
id: string;
username: string;
}
type Schema = HttpSchema<{
'/users': {
GET: {
request: {
searchParams: { page?: number; limit?: number };
};
response: {
200: { body: User[] };
};
};
};
}>;
const fetch = createFetch<Schema>({
baseURL: 'http://localhost:80',
});
fetch.onRequest = (request) => {
if (fetch.isRequest(request, 'GET', '/users')) {
const url = new URL(request.url);
url.searchParams.append('limit', '10');
const updatedRequest = new Request(url, request);
return updatedRequest;
}
return request;
};
Related:
fetch.onResponse
A listener function that is called after receiving each response.
Type: (response: FetchResponse.Loose) => Promise<Response> | Response
Arguments:
-
response:
FetchResponse.Loose
The response received from the server.
Returns: Promise<Response> | Response
The response to use, either a modified version of the original response or a new one.
import { HttpSchema } from '@zimic/http';
import { createFetch } from '@zimic/fetch';
interface User {
id: string;
username: string;
}
type Schema = HttpSchema<{
'/users': {
GET: {
response: {
200: {
headers: { 'content-encoding'?: string };
body: User[];
};
};
};
};
}>;
const fetch = createFetch<Schema>({
baseURL: 'http://localhost:80',
});
fetch.onResponse = (response) => {
if (fetch.isResponse(response, 'GET', '/users')) {
console.log(response.headers.get('content-encoding'));
}
return response;
};
Related:
fetch.loose
A loosely-typed version of fetch
. This can be useful to make requests with fewer type constraints, such as in
onRequest
and onResponse
listeners.
fetch.loose(input);
fetch.loose(input, init);
Arguments:
-
input:
string | URL | FetchRequest
The resource to fetch, either a path, a URL, or another
FetchRequest
request. If a path is provided, it is automatically prefixed with the base URL of the fetch instance when the request is sent. If a URL or a request is provided, it is used as is. -
init:
FetchRequestInit
The options to use for the request. If a path or a URL is provided as the first argument, this argument is required and should contain at least the method of the request. If the first argument is a
FetchRequest
, this argument is optional. The options inherit from the nativeRequestInit
interface, with the following additional properties:-
method:
string | undefined
The HTTP method to use for the request.
-
baseURL:
string | undefined
The base URL for the request. If provided, it will have preference over the default base URL of the fetch instance.
-
searchParams:
HttpSearchParamsSchema.Loose | undefined
The search parameters to be sent with the request. If provided, it will have preference over the default search parameters of the fetch instance.
-
See our authentication guide for an example of how to
use fetch.loose
.
fetch.Request
A constructor for creating a FetchRequest
instance, which inherits from
the native Request and receives the same arguments as fetch
.
new fetch.Request(input);
new fetch.Request(input, init);
Arguments:
-
input:
string | URL | FetchRequest
The resource to fetch, either a path, a URL, or another
FetchRequest
request. If a path is provided, it is automatically prefixed with the base URL of the fetch instance when the request is sent. If a URL or a request is provided, it is used as is. -
init:
FetchRequestInit | undefined
The options to use for the request. If a path or a URL is provided as the first argument, this argument is required and should contain at least the method of the request. If the first argument is a
FetchRequest
, this argument is optional. The options inherit from the nativeRequestInit
interface, with the following additional properties:-
method:
string
The HTTP method to use for the request.
-
baseURL:
string | undefined
The base URL for the request. If provided, it will have preference over the default base URL of the fetch instance.
-
searchParams:
HttpSearchParamsSchema.Loose | undefined
The search parameters to be sent with the request. If provided, it will have preference over the default search parameters of the fetch instance.
-
Related:
fetch.isRequest
A type guard that checks if a request is a FetchRequest
, was created by
the fetch instance, and has a specific method and path. This is useful to narrow down the type of a request before using
it.
fetch.isRequest(request, method, path);
Arguments:
-
request:
unknown
The request to check.
-
method:
string
The method to check.
-
path:
string
The path to check.
Returns: boolean
true
if the request was created by the fetch instance and has the specified method and path; false
otherwise.
import { HttpSchema } from '@zimic/http';
import { createFetch } 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 fetch.Request('/users', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ username: 'me' }),
});
if (fetch.isRequest(request, 'POST', '/users')) {
// request is a FetchRequest<Schema, 'POST', '/users'>
const contentType = request.headers.get('content-type'); // 'application/json'
const body = await request.json(); // { username: string }
}
fetch.isResponse
A type guard that checks if a response is a FetchResponse
, was received
by the fetch instance, and has a specific method and path. This is useful to narrow down the type of a response before
using it.
fetch.isResponse(response, method, path);
Arguments:
-
response:
unknown
The response to check.
-
method:
string
The method to check.
-
path:
string
The path to check.
Returns: boolean
true
if the response was received by the fetch instance and has the specified method and path; false
otherwise.
Example:
import { HttpSchema } from '@zimic/http';
import { createFetch } from '@zimic/fetch';
interface User {
id: string;
username: string;
}
type Schema = HttpSchema<{
'/users': {
GET: {
request: {
searchParams: { query?: string };
};
response: {
200: { body: User[] };
};
};
};
}>;
const fetch = createFetch<Schema>({
baseURL: 'http://localhost:3000',
});
const response = await fetch('/users', {
method: 'GET',
searchParams: { query: 'u' },
});
if (fetch.isResponse(response, 'GET', '/users')) {
// response is a FetchResponse<Schema, 'GET', '/users'>
const users = await response.json(); // User[]
}
fetch.isResponseError
A type guard that checks if an error is a FetchResponseError
related to a
FetchResponse
received by the fetch instance with a specific method and
path. This is useful to narrow down the type of an error before handling it.
fetch.isResponseError(error, method, path);
Arguments:
-
error:
unknown
The error to check.
-
method:
string
The method to check.
-
path:
string
The path to check.
Returns: boolean
true
if the error is a response error received by the fetch instance and has the specified method and path; false
otherwise.
import { HttpSchema } from '@zimic/http';
import { createFetch } from '@zimic/fetch';
interface User {
id: string;
username: string;
}
type Schema = HttpSchema<{
'/users': {
GET: {
request: {
searchParams: { query?: string };
};
response: {
200: { body: User[] };
400: { body: { message: string } };
500: { body: { message: string } };
};
};
};
}>;
const fetch = createFetch<Schema>({
baseURL: 'http://localhost:3000',
});
try {
const response = await fetch('/users', {
method: 'GET',
searchParams: { query: 'u' },
});
if (!response.ok) {
throw response.error; // FetchResponseError<Schema, 'GET', '/users'>
}
} catch (error) {
if (fetch.isResponseError(error, 'GET', '/users')) {
// error is a FetchResponseError<Schema, 'GET', '/users'>
const status = error.response.status; // 400 | 500
const { message } = await error.response.json(); // { message: string }
console.error('Could not fetch users:', { status, message });
}
}
Related: