UNPKG

@reggieofarrell/axios-retry-client

Version:

A class based api client for both the server and browser built on `axios` and `axios-retry`, written in TypeScript

265 lines (209 loc) 8.12 kB
# Axios Retry Client A class based api client for both the server and browser built on `axios` and `axios-retry`, written in TypeScript ## Installation ```bash npm install @reggieofarrell/axios-retry-client ``` ## `1.x` Breaking Changes `maxRetries`, `initialRetryDelay`, `exponentialBackoff` config options have been removed in favor of just exposing the entire `axios-retry` configuration via a `retryConfig` option. A `enableRetry` option was also added which defaults to `false`. ## `2.x` Breaking Changes `enableRetry` was removed in favor of just honoring `retryConfig.retries` which defaults to `0`. To enable retries, pass a minimum `retryConfig` of `{ retries: number }` ## Usage ### Configuration Options The `AxiosRetryClient` accepts the following configuration options: - `axiosConfig`: Configuration for the underlying [axios instance](https://axios-http.com/docs/instance). - `baseURL`: Base URL for the API. - `debug`: Whether to log request and response details. - `debugLevel`: Debug level. 'normal' will log request and response data. 'verbose' will log all axios properties for the request and response. - `name`: Name of the client. Used for logging. - `retryConfig`: Extended configuration for `axios-retry` See https://www.npmjs.com/package/axios-retry for more details. The default config if you don't override it is `{ retries: 0, retryDelay: axiosRetry.exponentialDelay, retryFactor: 500, backoff: 'exponential' }`. You can override individual properties in the `retryConfig` and they will be merged with the default. We add `retryFactor` and `backoff` to the standard `axios-retry` config in order to make configuring the retry delay easier. Otherwise you'd have to create your own `retryDelay` function (which you can still do if you like) For more details, refer to the [source code](src/axios-retry-client.ts). ### Basic Setup ```typescript import { AxiosRetryClient } from '@reggieofarrell/axios-retry-client'; const client = new AxiosRetryClient({ baseURL: 'https://api.example.com', name: 'ExampleClient', retryConfig: { retries: 2 } }); ``` ### Making Requests #### GET Request ```typescript const { data } = await client.get('/endpoint'); console.log(data); ``` #### POST Request ```typescript const { data } = await client.post('/endpoint', { key: 'value' }); console.log(data); ``` #### PUT Request ```typescript const { data } = await client.put('/endpoint', { key: 'updatedValue' }); console.log(data); ``` #### PATCH Request ```typescript const { data } = await client.patch('/endpoint', { key: 'patchedValue' }); console.log(data); ``` #### DELETE Request ```typescript const { data } = await client.delete('/endpoint'); console.log(data); ``` ### Accessing the underly Axios request Requests return `request` and `data` with `request` being the underlying `axios` request in case you need to dig into this. ```typescript const { request, data } = await client.get('/endpoint'); console.log(data); ``` ### Type responses ```typescript // pass a generic if you're using typescript to get a typed response const { data } = await client.get<SomeResponseType>('/endpoint') ``` ### Custom request config Pass an [AxiosRequestConfig](https://axios-http.com/docs/req_config) as the final argument for any of the request methods to customize the request config for a specific request (additional headers, etc) ```typescript const { data } = await client.get('/endpoint', { headers: { 'X-Some-Header': 'value' }, timeout: 5000 }) ``` In addition to the [AxiosRequestConfig](https://axios-http.com/docs/req_config) options, you can also pass override options for `retryConfig` per request ```typescript const { data } = await client.get('/endpoint', { retryConfig: { retries: 5, delayFactor: 1000, backoff: 'linear' } }) ``` ### Disable TLS checks (server only) If necessary you can disable the TLS checks in case the server you are hitting is using a self-signed certificate or has some other TLS issue ```typescript const client = new AxiosRetryClient({ baseURL: 'https://api.example.com', name: 'ExampleClient', axiosConfig: { httpsAgent: new https.Agent({ rejectUnauthorized: false, }); } }); ``` ### Logging / Error Handling The client includes built-in error handling that logs detailed information based on the debug level. For more granular control, you can extend the AxiosRetryClient class to implement your own `errorHandler` function ### Extending AxiosRetryClient is meant to be extended for the purpose of interacting with a specific api. This way you can set common headers, create your own error handling function that is specific to the api you are consuming, etc. This is a basic example... ```typescript import { ApiResponseError, AxiosRetryClient } from '@reggieofarrell/axios-retry-client'; const defaultHeaders = { Authorization: `Basic ${process.env.MY_AUTH_TOKEN}` }; export class CustomApiClient extends AxiosRetryClient { constructor() { super({ baseURL: 'https://api.example.com', name: 'Example API Client', retryConfig: { retries: 2 } axiosConfig: { headers: { Authorization: `Basic ${process.env.MY_AUTH_TOKEN}` } } }) } protected errorHandler = (error: any, reqType: RequestType, url: string) { /** * do your custom error handline logic based on the docs for * the API you are consuming. * https://axios-http.com/docs/handling_errors */ } // optionally build out your own SDK of sorts like so... someEndpointGroup = { get: async (): Promise<SomeTypedResponse> => { return (await this.get('/some-endpoint-group/something')) } } /** * Note: * * If you are going to follow the pattern above of namespacing groups of endpoints, * make sure to use arrow functions so that 'this' is correctly bound to the class instance */ } // In some other file... import { CustomApiClient } from './CustomApiClient'; const client = new CustomApiClient(); const { data } = await client.someEndpointGroup.get(); // or simply... const { data } = await client.get('/some-endpoint'); ``` ### Hooks If you are extending AxiosRetryClient to create your own class, there are some class methods you can override to hook into the request lifecycle. #### preRequestFilter ```typescript /** * Called before the request is actually sent. * * Define this method in your extending class to globally modify the * request data or config before the request is sent. * * @param requestType - The request type (GET, POST, PUT, PATCH, DELETE) * @param url - The request URL * @param data - The request data * @param config - The request config */ preRequestFilter( requestType: RequestType, url: string, data?: any, config: AxiosRequestConfig = {} ): { data?: any; config: AxiosRequestConfig } { // do something to modify `data` or `config` return { data, config }; } ``` #### preRequestAction ```typescript /** * Called after `beforeRequestFilter` but before the request is sent. * * Define this requestType in your extending class to perform any actions before * the request is sent such as logging the request details. * * @param requestType - The request type (GET, POST, PUT, PATCH, DELETE) * @param url - The request URL * @param data - The request data * @param config - The request config */ protected preRequestAction( requestType: RequestType, url: string, data?: any, config: AxiosRequestConfig = {} ): void { // do some logging, etc } ``` ## License This project is licensed under the 0BSD License. See the [LICENSE](license.txt) file for details. ## Dependencies This project is build on top of the following open-source libraries: - [axios](https://github.com/axios/axios) - Promise based HTTP client for the browser and node.js (MIT License) - [axios-retry](https://github.com/softonic/axios-retry) - Axios plugin that intercepts failed requests and retries them whenever possible (Apache License 2.0) For full license texts, please refer to the respective project repositories.