Skip to content

Axios plugin to transform data requests/responses based on a schema.

Notifications You must be signed in to change notification settings

nobrainr/axios-morphism

Repository files navigation

axios-morphism

npm npm bundle size (minified) Coveralls github CircleCI (all branches) Deps

Axios plugin to transform data requests/responses based on a schema.

This package is built upon Morphism. Read the documentation here.


Getting started

Installation

npm install --save axios morphism # Axios and Morphism are defined as a peer dependencies in axios-morphism
npm install --save axios-morphism

Example

import axios from 'axios';
import { apply, AxiosMorphismConfiguration } from 'axios-morphism';

const peopleSchema = {
  name: 'name',
  height: 'height',
  weight: 'mass'
};

const configuration: AxiosMorphismConfiguration = {
  url: 'https://swapi.co/api/',
  interceptors: {
    responses: [
      { matcher: '/people', schema: peopleSchema, dataSelector: 'results' },
      { matcher: '/people/:id', schema: peopleSchema }
      ],
    requests: []
  }
};

const client = axios.create({baseURL: 'https://swapi.co/api/'});
apply(client, configuration);

await client.get('/people/1');

// {
//   name: "Luke Skywalker"
//   height: "172"
//   weight: "77"
// }

await client.get('/people');

// [
//  {
//    name: "Luke Skywalker"
//    height: "172"
//    weight: "77"
//  },....
// ]

Try on Repl.it

Usage

Schema

Define a schema corresponding to the shape you expect to have after the transformation has been applied.

Read About Morphism's Schema Capabilities

const peopleSchema = {
  name: 'name',
  height: 'height',
  weight: ({ mass }) => `${mass} KG`
};

Interceptors Configuration

Create your configurations to be applied on Axios requests or responses.

Example:

const configuration: AxiosMorphismConfiguration = {
  url: 'https://swapi.co/api/',
  interceptors: {
    responses: [
      { matcher: '/people', schema: peopleSchema, dataSelector: 'results' },
      { matcher: /\/people\/([^\/]+?)(?:\/)?$/i, schema: peopleSchema }, // matches /people/:id
      {
        matcher: (response: AxiosResponse) => response.config.method === 'POST', // matches every responses obtained using a POST
        schema: peopleSchema,
        dataSelector: 'results'
      }
    ],
    requests: []
  }
};

Axios-Morphism Configuration

Property Type Description Example
url string Base URL to listen on https://swapi.co/api
interceptors { responses: [], requests: []}; List of Responses and Requests Interceptors Configuration to register against Axios
interceptors.responses[].matcher string RegExp Function Matcher used to detect on which response to apply the transformer - 'people/:id'
- /people$/i
- (response: AxiosResponse) => response.config.method === 'POST'
interceptors.requests[].matcher string RegExp Function Matcher used to detect on which request to apply the transformer - 'planets/:id'
- /planets$/i
- (request: AxiosRequestConfig) => request.url.includes('planets')
interceptors.requests[].schema interceptors.responses[].schema Schema StrictSchema A schema is an object-preserving map from one data structure to another. Morphism Schema Examples
interceptors.requests[].dataSelector interceptors.responses[].dataSelector string A selector to access the data in the Axios returned data With this Axios Response: { data: { results: [] }}. Pick the data with { dataSelector: 'results' }

Apply Configurations

Apply your interceptors on your axios instance and there you go!

import { apply } from 'axios-morphism';

const configuration: AxiosMorphismConfiguration = {
  url: 'https://swapi.co/api/',
  interceptors: {
    responses: [
      { matcher: '/people', schema: peopleSchema, dataSelector: 'results' },
      { matcher: /\/people\/([^\/]+?)(?:\/)?$/i, schema: peopleSchema } // Will match /people/:id
    ],
    requests: []
  }
};

const client = axios.create({ baseURL: 'https://swapi.co/api/' });
apply(client, configuration);

// Start making requests to see you data transformed
await client.get('/people');
await client.get('/people/1');

Remove Configurations

Use the unsubscribe method returned from the apply function to opt-out from the interceptors

const configuration: AxiosMorphismConfiguration = {...};

const axiosMorphism = apply(client, config);
axiosMorphism.unsubscribe(); // Remove all registered interceptors

Combine Configurations

axios-morphism provides the combine function in order to help you merge multiple configurations under a baseURL.

import { apply, combine, AxiosMorphismConfiguration } from 'axios-morphism';

const peopleMorphism: AxiosMorphismConfiguration = {
  url: '/people',
  interceptors: {
    requests: [],
    responses: [
      { matcher: '/', schema: { name: 'name', url: 'url' }, dataSelector: 'results' },
      { matcher: '/:id', schema: { name: 'name', url: 'url' }, dataSelector: 'results' }
    ]
  }
};
const planetMorphism: AxiosMorphismConfiguration = {
  url: '/planets',
  interceptors: {
    requests: [],
    responses: [
      { matcher: '/', schema: { name: 'name', url: 'url' }, dataSelector: 'results' },
      { matcher: '/:id', schema: { name: 'name', url: 'url' }, dataSelector: 'results' }
    ]
  }
};

const client = axios.create({ baseURL: 'https://swapi.co/api/' });
apply(client, combine('https://swapi.co/api/', peopleMorphism, planetMorphism));

// Start making requests to see you data transformed
await client.get('/people');
await client.get('/planets/1');

License

MIT © Yann Renaudin