react-http-request-handler
TypeScript icon, indicating that this package has built-in type declarations

1.1.1 • Public • Published

React Http Request Handler (RH2)

Quality Gate Status Coverage Renovate Build Status Maintenance GitHub license React React Native

French documentation

Table of Contents

Contexte

This React library using customized hooks is aimed to help users handling HTTP requests. The request and its trigger are simply configured, then executed by Axios. Optional parameters can also be configured depending on the client needs. For example :

  • Configuring the request to be executed once through our historization module
  • Configuring methods to be called in case of error Redux users will find means to dispatch the request’s result, whether it was successfully handled or not. The response can be processed before being dispatched.

Functionalities

  • Everything Axios can already do
  • Adding a global configuration (instance management, HTTP error handling, request filtering, .. etc)
  • Coupling with redux
  • Allowing less code production
  • Easily cancel a request

Installation

Using npm :

$ npm install react-http-request-handler

Using yarn :

$ yarn add react-http-request-handler

Configurations

In the project sources, there is a folder named example in which you can see configuration examples (be careful, it's a bit of a mess...).

Library usage

You can initialize your application by :

Using a wrapper wherein the initial configuration is parametrized :

import { Rh2Initializer, Rh2InitializationParameter } from 'react-http-request-handler';

const initSettings: Rh2InitializationParameter = {
  debugMode: true
};
 
<Rh2Initializer rh2Settings={initSettings}>
  <App />
</Rh2Initializer>

Or by using a service later on :

import { Rh2InitializationParameter, rh2ConfigService } from 'react-http-request-handler';

const initSettings: Rh2InitializationParameter = {
  debugMode: true
};
rh2ConfigService.initializeParameters(initSettings);

Finally, if you do not initialize the app, a default instance is used.

If a new instance configuration is injected during runtime, the old one and its injectors are deactivated.

Using two hooks

Hooks without preloading

const axiosConfig: AxiosRequestConfig = {
    url: `https://jsonplaceholder.typicode.com/todos/1`,
    method: 'GET' 
};
const configuration: Rh2EffectAxiosConfigHandler = {
    axiosRequestConfig: axiosConfig
};

const test = useRh2WithParameters(configuration);
console.log(test);

Log result will be :

{
    loading: false,
    data: {
        userId: 1,
        id: 1,
        title: "delectus aut autem",
        completed: false
    }
}
Other example :
const App = () => {
    const initSettings: Rh2InitializationParameter = {
        axiosConfig: [
            {
                key: 'Test1',
                axiosConfig: { baseURL: 'https://www.google.com/', method: 'POST' },
                defaultInterceptor: true,
                headerUrl: [
                    {
                        key: 'CleDeTest',
                        value: 'value to test'
                    }
                ]
            },
            {
                key: 'Test2',
                axiosConfig: { baseURL: 'https://jsonplaceholder.typicode.com' },
                defaultInterceptor: false,
                headerUrl: []
            }
        ],
        debugMode: true
    };

    return (
    <Provider store={Store}>
        <Rh2Initializer rh2Settings={initSettings} >
            <Navigation />
        </Rh2Initializer>
        </Provider>
    );
};
const dispatch = useDispatch();

const axiosConfig: AxiosRequestConfig = {
    url: `/todos/1`,
    method: 'GET'
};

const configuration: Rh2EffectAxiosConfigHandler = {
    axiosRequestConfig: axiosConfig,
    onlyResult: false,
    keyOfInstance: 'Test2',
    successHandler: (value) => dispatch(pourTestAction(value))
};

useRh2WithParameters(configuration);

In configuration initialization, 2 Axios instances were created

keyOfInstance: 'Test2' process the request from instance named Test2. If Test1 or nothing is specified, the result will be different. By default, the first instance specified during initialization is used .

For this example, the parameter successHandler is used to dispatch a redux action, which get the response from the request onlyResult: false.

Following is the action processed :

{
  type: 'POUR_TEST_ACTION',
  payload: {
    data: {
      userId: 1,
      id: 1,
      title: 'delectus aut autem',
      completed: false
    },
    status: 200,
    statusText: '',
    headers: {
      ...
    },
    config: {
      url: '/todos/1',
      method: 'get',
      headers: {},
      baseURL: 'https://jsonplaceholder.typicode.com',
      ...
    },
    request: {}
  }
}
Handling error example

If the errorHandler parameter from Rh2Initializer wrapper is ignored during initialization, you can still define an handler later on, like the following :

 const traitementErreur = (data: ResponseFetchApi) => {
     let message;

     switch (data.status) {
         case 405:
             message = 'C’est une erreur 405 !';
             dispatch(pourTestAction(message));
             break;
         case 404:
             message = 'C’est une erreur 404 !';
             dispatch(pourTestAction(message));
             break;
         default:
             message = 'Facheux ce problème !';
             dispatch(pourTestAction(message));
             break;
     }
 };

rh2ConfigService.setErrorHandler(traitementErreur);

This test was done using our previous example, while executing the request with instance Test1.

Google is not expecting requests like https://www.google.com/todos/1 : a 404 error is raised.

Action processed :

{
  type: 'POUR_TEST_ACTION',
  payload: 'C’est une erreur 404 !'
}

You can do anything you want to do. We can also dispatch an action with the data contained within the arguments of traitementErreur method.

Preloaded Hook

In the next example the code is compiled, but you can write a configuration file where all configurations are defined.

Then you can call the hook useRh2WithName in your component :

const axiosConfig: AxiosRequestConfig = {
	url: '/search?q=champ',
	method: 'GET'
};
const configACharger: Rh2AxiosConfig = {
	keyOfInstance: 'Test1',
	axiosRequestConfig: axiosConfig,
	label: GOOGLE
};

rh2AxiosConfigService.addConfigAxios(configACharger);

const test = useRh2WithName(GOOGLE);
console.log(test);

Hook with parameters

Second argument of hooks useRh2WithName and useRh2WithParameters is used to specify what to expect from the request.

useRh2WithName(GOOGLE, {
        pathParams: '/to/test',
        params: {
            hat: 'red',
            hair: 'grey'
        },
        data: {
            color: 'yellow',
            shape: 'square'
        }
    });

Response will be :

https://www.google.com/search/to/test?hat=red&hair=grey

With key/value pairs in data property in the response body.

Depending on your use case, you can also use rh2AxiosConfigService service to do the body injection.

rh2AxiosConfigService.addBodyToConfigAxios(GOOGLE, {
    color: 'yellow',
    shape: 'square'
});

Axios instance

You can use Axios generated instances, by getting it from service rh2ConfigService.

Caution : : For custom instance initialization, you have to fill in the property "defaultInterceptor" à "false"
const axiosInstance: AxiosInstance = rh2ConfigService.getAxiosInstance('TEST2');
axiosInstance.interceptors.request.use(
    async (config) => {
        const headerImpl = await getHeader();

        if (headerImpl) {
            if (config.method !== 'OPTIONS') {
                config.headers = headerImpl;
            }
        }
        return config;
    },
    ...
);

In the previous use case, we get TEST2 instance, then create an interceptor. This use case could be implemented for example to add a token in the request header.

If you need to configure the URL with BASIC authentication, you can follow the next example :

rh2AxiosConfigService.addAuthToConfigAxios(GOOGLE, {
	username: 'toto',
	password: 'I1€5t3nGerr€'
});

Services

Rh2DirectoryService

Initialize the app :

  • Management of requests stored in memory to prevent them from being executed again
Méthode type Description
hasConfigQueryParameter(url: string, method: Rh2Method, params?: Rh2Param) boolean Check the presence of the configuration
hasConfigQueryParameterByConfigQueryParameter(parameter: ConfigQueryParameter) boolean Check the presence of the configuration
addConfigQueryParameter(configTmp: ConfigQueryParameter) void Add a configuration to the directory
getConfigQueryParameters() ConfigQueryParameter[] Retrieve the list of configurations
getConfigQueryParameter(url: string, method: Rh2Method, params?: Rh2Param) ConfigQueryParameter Retrieve a specific configuration
removeQueryDirectory(axiosRequestConfig: AxiosRequestConfig) void Delete a specific configuration
removeAllQueryDirectory() void Delete all configurations in memory

Rh2ConfigService

Initialize the app :

  • Configures Axios instances (if no configuration is provided, a default instance is generated)
  • Configures debug mode
  • Adds a handler for request errors, which can be handled by error type and error code of the request
Method Type Description
initializeParameters(parameters: Rh2InitializationParameter) void Initialize a new configuration
setErrorHandler(treatment: (param?: any) => void) void Set an error handler, which is used for all failed requests, unless it is overriden in the request parameters
getParameters() Rh2InitializationParameter Return service parameters
getParametersAxiosConfigs() AxiosRequestConfigExtended[] Return configuration sent by the consumer
isdebugMode() boolean Return true if debug mode is activated
getAxiosInstances() Rh2AxiosInstance Return all Axios instancei
getAxiosInstance(key: string) AxiosInstance Return the Axios instance specified in parameter

Rh2AxiosConfigService

Initialize the app :

  • Handle preloaded configuration
Méthode type Description
getAllConfigAxios() Rh2AxiosConfig[] Return all Axios configurations
getConfigAxios(label: string) Rh2AxiosConfig Return the Axios configuration specified in parameter
hasConfigAxios(label: string) boolean Return true if the configuration in parameter was added
addConfigAxios(configAxios: Rh2AxiosConfig) void Add a new configuration in parameter
addAuthToConfigAxios(label: string, auth: { username: string, password: string }) void Add authentication information to an existing configuration in parameter
addBodyToConfigAxios(label: string, body: T) void Add body information to an existing configuration in parameter
replaceConfig(label: string, configAxios: Rh2AxiosConfig) void Replace the instance in 1st argument by the one in 2nd
removeConfigAxios(label: string) void Delete an existing configuration, specified in parameter
removeAllConfigAxios() void Delete all existing configurations

Http error history

Each query you will execute will have been configured beforehand, with a label or not. If a request fails, it is logged with the label as key, if not, a hash is used. For each configuration, the last error that occurred is kept (eg: error code 404, 500, etc.).

You can access the list through this method :

import { getErrorsApi } from 'react-http-request-handler';

getErrorsApi();

Rh2 model list

Parameters for non-preloaded requests

Rh2EffectAxiosConfigHandler
export interface Rh2EffectAxiosConfigHandler {
    readonly keyOfInstance?: string;
    readonly axiosRequestConfig: AxiosRequestConfig;
    readonly onlyResult?: boolean;
    readonly errorHandler?: OptionalParamVoidMethod
    readonly successHandler?: OptionalParamVoidMethod,
}

keyOfInstance keyOfInstance if the value is not provided, first generated instance is used. If only one instance was provided during configuration initialization, or if none, this field can be ignored.

axiosRequestConfig Axios configuration.

lock This is used if we want to execute once the request during runtime. This value can be updated with Rh2DirectoryService.

Caution : The request filter depends on URL, method type and params property.

onlyResult This allows to choose if the request response provides only the content of data (true), or all the configuration (false). Default is true.

successHandler This field is mandatory to get a response if there is no listener for the hook return. Example : using redux to dispatch an action.

errorHandlerIf provided, overrides Rh2ConfigService property. During debug mode, if none is provided, a message will be displayed. It can be a nominal case, unless there is no listener for the hook : in this case, you have to define an errorHandler.

Rh2EffectData
export interface Rh2EffectData {
    readonly data?: any;
    readonly params?: any;
    readonly pathParams?: any;
}

data Request body.

params Request query parameter.

pathParams Request path parameters.

NB : If params and pathParams are provided, pathParams is built first.

AxiosConfig

Request configuration.

export interface Rh2AxiosConfig extends Rh2EffectAxiosConfigHandler {
    readonly label: ConfigAxiosTrigger;
}

label Used to find a preloaded configuration.

FetchApi

Management of request returns.

ResponseFetchApi
export interface ResponseFetchApi {
    readonly isSuccess: boolean;
    readonly isError: boolean;
    readonly responseSuccess: AxiosResponse;
    readonly responseErreur: ErreurFetchApi;
    readonly status: number;
}
ErreurFetchApi
export interface ErreurFetchApi {
    readonly isResponseError: boolean;
    readonly isRequestError: boolean;
    readonly responseError: AxiosError;
    readonly requestError: any;
    readonly messageError: string;
    readonly config: AxiosRequestConfig;
}

General configuration

Following types are used with Rh2ConfigService

Rh2InitializationParameter
export interface Rh2InitializationParameter {
    axiosConfig?: AxiosRequestConfigExtended[];
    errorHandler?: (param?: any) => void;
    debugMode?: boolean
}
AxiosRequestConfigExtended
export interface AxiosRequestConfigExtended {
    key: string;
    axiosConfig: AxiosRequestConfig;
    defaultInterceptor?: boolean;
    headerUrl?: KeyValue<string>[];
}

Rh2InitializationParameter

Nom Type Description Valeur par défaut Valeur d’exemple
axiosConfig AxiosRequestConfigExtended[] Requests executed during runtime can be preconfigured. Using a label will be needed to find the added configuration [] Example 1
debugMode boolean Activates the debug mode : more information will be logged false true, false
errorHandler function Provides a method to be used during request fail n/a Example 2

AxiosRequestConfigExtended

Nom Type Description Valeur par défaut Valeur d’exemple
key string Value to find Axios instance and to configure requests, You have to provide the instance targeted. If none is provided, the system will use the first on added n/a "MY_DEFAULT_KEY"
axiosConfig AxiosRequestConfig Axios configuration. If you do not know this library, you can for example set the baseURL property to point out the prefix of each URL using this instance. n/a { baseURL: 'http://test.fr' }
defaultInterceptor boolean If null or true, then an interceptor will be automatically created for this instance. The headerUrl property must beprovided. You can create your own interceptor by retrieving the instance from the built-in service.
If for a specific instance a default interceptor was created, you cannot use yours.
true true, false
headerUrl {key: string;
value: string;}[]
Header list to be used by the interceptor [{key: 'Content-Type', value: 'application/json'}] [{key: 'Content-Type', value: 'application/json'}]

Example 1 :

{
  key: 'Test1',
  axiosConfig: { 
      baseURL: 'https://www.test.com/',
      method: 'GET' 
  },
  defaultInterceptor: true,
  headerUrl: [{
      key: 'key',
      value: 'value to test'
  }]
}

Example 2 :

const traitementErreur = (data: ResponseFetchApi) => {
    let message;

    switch (data.status) {
      case 405:
        message = 'C’est une erreur 405 !';
        console.log(message);
        dispatch(pourTestAction(message));
        break;
      case 404:
        message = 'C’est une erreur 404 !';
        console.log(message);
        dispatch(pourTestAction(message));
        break;
      default:
        message = 'Facheux ce problème !';
        console.log(message);
        dispatch(pourTestAction(message));
        break;
    }
}

const initSettings: Rh2InitializationParameter = {
    debugMode: true,
    errorHandler: (data) => traitementErreur(data)
};

Error history

Rh2ErrorsApi
interface Rh2ErrorsApi {
    label: string;
    configuration: Rh2EffectTreatmentToManageRequest;
    error: ResponseFetchApi;
}

Roadmap

If you have recommendations, we can analyze the need !

Table of contents generated with markdown-toc

Package Sidebar

Install

npm i react-http-request-handler

Weekly Downloads

0

Version

1.1.1

License

MIT

Unpacked Size

379 kB

Total Files

112

Last publish

Collaborators

  • lunotte