@personio/request
TypeScript icon, indicating that this package has built-in type declarations

2.1.0 • Public • Published

@personio/request

A helper library used in Personio UI to perform HTTP requests. It also takes care to include the X-CSRF-Token on every request. Written in TypeScript, uses axios in the background.

Installation

Run

yarn add @personio/request

Usage

In the root of your project, import configureRequest and execute it to provide a configuration to subsequent requests performed using the library:

import { configureRequest } from '@personio/request';

configureRequest({ baseURL: API_BASE_URL, 
                   timeout: REQUEST_TIMEOUT,
                // Default is false. When enabled, returns the data content instead of an object with data as prop.
                // This is useful to avoid something like data.data when mapping the response. 
                   retrieveDataFromResponse: true,
                // Default is false, when enabled, dispatches the SESSION:EXPIRED event.
                // This makes the login modal from the monolith be triggered.  
                   dispatchSessionExpiredEvent: true,
                // Number in milliseconds, default is 0. Adds a delay to the session expired event.
                // Useful for finishing some animations like a closing a modal before it shows the login modal.
                   sessionExpiredDelay: 300 
                });

Perform an actual HTTP request anywhere in the code:

import request from '@personio/request';
 
const response = await request({ method: "GET", url: 'example' }); 

Behind the scenes, request passes the arguments as is to axios. See more about possible options on https://github.com/axios/axios.

With useRequest hook

It's possible to perform HTTP requests directly in React components or create custom React hooks using the useRequest hook provided by the library:

import { useRequest, wasRequestSuccessful } from '@personio/request'; 
import { useCallback, useEffect } from "react";

type DataType = { id: number, value: string };
type MetaType = { example: string };

const useRequestExample = () => {  
  const [
      {
        data = [],
        statusCode,
        hasRequested,
        cancelSource,
        meta,
        isLoading,
        error,
      },
      makeRequest,
      { resetData, setHasNotRequested }
    ] = useRequest<DataType[], MetaType>();
  
  const fetch = useCallback((id: number) =>
    makeRequest(
      {
        method: 'GET',
        url: `example/${id}`,
      }      
    ), [makeRequest]);

  useEffect(() => {
    if (!statusCode) {
      return;
    }

    if (wasRequestSuccessful(statusCode)) {
      // do some action on success
    } else {
      // do some action on fail
    }
  }, [statusCode]);

  return [
   { data, meta, isLoading, error, statusCode, hasRequested, cancelSource },
   { fetch, resetData, setHasNotRequested }
  ] as const;
};

export default useRequestExample

The makeRequest function can also accept a second argument, an object that defines request options:

{
  // prop to indicate if we should clear or persist the data between requests.
  // default: false
   persistData: boolean
}

Testing

Use createMock and mockResponse

import request, { createMock, mockResponse, getRequestAmount } from '@personio/request';
import { render, screen } from '@testing-library/react';

type Response = {
  data: { id: number; text: string }[];
};

const mockAdapter = createMock(request);

const exampleMock = mockResponse({ method: 'GET', url: /example/ });

describe('<Example/>', () => {
  beforeEach(() => {
      exampleMock.reply<Response>(200, { data: [{id: 1, text: 'example'}] });
    });
  afterEach(() => {
      mockAdapter.reset();
  });
 
  it('should render with text "example"', async () => {    
      render(<Example />);
        
      expect(await screen.findByText('example')).toBeInTheDocument();      
  });
  
  it('should call the example API only once"', async () => {
      render(<Example />);
  
      await screen.findByText('example')

      expect(getRequestAmount(mockAdapter.history.get, /example/)).toBe(1);      
  });  
  
});

The axios-mock-adapter with a modified API is used to mock HTTP requests. For more info, check https://github.com/ctimmerm/axios-mock-adapter.

Readme

Keywords

none

Package Sidebar

Install

npm i @personio/request

Weekly Downloads

610

Version

2.1.0

License

MIT

Unpacked Size

17.5 kB

Total Files

11

Last publish

Collaborators

  • personio-npm-ci
  • shovanco
  • riain-personio
  • remipersonio
  • personio_ci
  • rishatfrompersonio
  • rodrigopagnuzzi