@peassoft/request
v1.0.1
Published
Peassoft HTTP client library for Node.js
Readme
@peassoft/request
Peassoft HTTP client library for Node.js
You may not need it!
This is a custom, highly opinionated solution aimed at code re-use for a few private projects.
Installation
$ npm install @peassoft/requestUsage Example
import {
createRequestFunction,
type ApiDescriptor,
type CustomError,
} from 'mnr-request';
const apis: Map<string, ApiDescriptor> = new Map([
['httpbin', {
baseUrl: 'https://httpbin.org',
apiOptions: {
requestTimeoutMs: 5000,
retries: 5,
retryTimeoutMs: 500,
customErrors: new Map<Map<number, CustomError>>([
[401, { name: 'UnauthorizedError', message: 'request unauthorized' }]
])
}
}],
['example', { baseUrl: 'http://example.com' }],
]);
const globalOptions = {
requestTimeoutMs: 10000,
retries: 1,
retryTimeoutMs: 3000,
customErrors: new Map<Map<number, CustomError>>([
[409, { name: 'ConflictError', message: 'request resulted in 409 Conflict response' }],
])
};
const request = createRequestFunction(apis, globalOptions);
// Type of data we expect the endpoint to respond with
type ResponseData1 = {
foo: string;
};
const responseData1: ResponseData1 | null = await request<ResponseData1>({
apiName: 'httpbin',
path: '/get',
method: 'GET',
headers: {
authorization: 'Bearer 123foo=',
},
qs: {
foo: 'bar',
},
});
await request<void>({
apiName: 'example',
path: '/',
method: 'PUT',
body: {
foo: 'bar',
},
requestOptions: {
requestTimeoutMs: 0,
retries: 0,
retryTimeoutMs: 0,
customErrors: new Map<Map<number, CustomError>>([
[500, { name: 'CriticalError', message: 'backend is broken' }],
]),
},
});API Reference
Options
There are four levels of options:
- Default options - applied to all requests if no other options override them.
- Custom global options - override default options and are applied to all requests if not overriden by neither custom API options, nor custom request options.
- Custom API options - override both default and global options and are applied to all requests to a particular API.
- Custom request options - override all other options and are applied to this particular request.
Options object intarface:
type Options = {
/**
* Timeout in milliseconds after which a single request attempt/retry fails.
*
* 0 disables the setting (OS limit applies).
*/
requestTimeoutMs?: number;
/**
* Number of retries.
*
* This number does not include the initial request.
*
* Retries happen in case of:
*
* • request fails due to a technical reason;
*
* • response status code is 503, no custom error is configured for this status
* code, and response body JSON object DOES NOT contain a field `retry: false`;
*
* • response status code is 504.
*/
retries?: number;
/**
* Amount of time in milliseconds to wait before next retry.
*/
retryTimeoutMs?: number;
/**
* Collection of custom error descriptors a promise has to reject with for defined
* response status codes.
*
* A key of a map is response status code.
*/
customErrors?: Map<number, CustomError>;
};All fields in an Options object are optional. If a field is missing in a particular Options object, it just means that this option at a higher level is not overriden.
Default options:
{
requestTimeoutMs: 0,
retries: 2,
retryTimeoutMs: 2000,
customErrors: new Map<number, CustomError>(), // Empty collection
}Initializing request function
You should initialize request function once and then use it througout your app.
import {
createRequestFunction,
type ApiDescriptor,
type Options,
} from '@peassoft/request';
const apis: ApiDescriptor = ...
const globalOptions: Options = ...
export const request = createRequestFunction(apis, globalOptions);