简体   繁体   中英

Using es6 class to extend Axios

I'm interesting in creating an API wrapper and extending from axios using es6 classes. How is this possible? Axios has a method .create() which allows you to generate a new axios object

class Api extends Axios {
  constructor(...args){
    super(..args)
    this.defaults.baseURL = 'https://api.com'
  }
  cancelOrder (id) {
    return this.put(`/cancel/order/${id}`)
  }
}

I know I have access to this let instance = axios.create() .

Any thoughts?

Attempt 1

import axios from 'axios'
const Axios = axios.create()

class Api extends Axios {
  constructor (...args) {
    super(...args)
    this.defaults.baseURL = 'https://api.com'
  }
  cancelOrder (id) {
    return this.put(`/cancel/order/${id}`)
  }
}

let api = new Api()

api.cancelOrder('hi')
  .then(console.log)
  .catch(console.log)

Attempt 2

import axios from 'axios'

class Axios {
  constructor () {
    return axios.create()
  }
}

class Api extends Axios {
  constructor () {
    super()
    this.defaults.baseURL = 'https://api.com'
  }
  cancelOrder (id) {
    return this.put(`/cancel/order/${id}`)
  }
}

let api = new Api()

console.log(api.__proto__)

api.cancelOrder('hi')
  .then(console.log)
  .catch(console.log)

axios currently does not currently export the Axios object it uses internally.

The .create() method only instantiates a new instance.

// Factory for creating new instances
axios.create = function create(defaultConfig) {
  return new Axios(defaultConfig);
};

I created a pr that exports the Axios class.

https://github.com/reggi/axios/commit/7548f2f79d20031cd89ea7c2c83f6b3a9c2b1da4

And a github issue here:

https://github.com/mzabriskie/axios/issues/320

If you look at the source code of they do not seem to expose the "class" for Axios , only an instance.

I do not believe that an instance object can be extended in es6.


Your second attempt seems most viable, but if you want to emulate every single axios method, you may have a lot of overhead.

你可以安装这个包: npm i axios-es6-class

I also wanted to create class which would allow me to create multiple instances having predefined defaults. Here is my solution.

import axios from 'axios'

export class Axios {
    constructor() {
        return axios.create({
            baseURL: 'http://127.0.0.1:8080/',
            headers: {
                Authorization: 'AUTH TOKEN FROM INSTANCE',
                'Content-Type': 'application/json',
            },
        })
   }

}

const db = new Axios()

db.get('/your_url').then().catch()
import axios, { Axios } from 'axios';

class Api extends Axios {
  constructor () {
    super()
    this.defaults.baseURL = 'https://api.com'
  }
  cancelOrder (id) {
    return this.put(`/cancel/order/${id}`)
  }
}

Well, many of the answers says that there's no class "Axios" exported from the axios package but that's not true atleast for version 0.26.0. Well if you want to create the Axios instance by yourself and customize it as you wish is pretty simple. I created a example using typescript feel free to use it if you want.

import { Axios, AxiosRequestConfig } from "axios";

class AxiosService<D = any> extends Axios {
  constructor(config?: AxiosRequestConfig<D>) {
    super(config);
    this.defaults.baseURL = 'https://api.com'
    
    this.interceptors.request.use(interceptorConfig => {
      // Set up your default interceptor behavior here for requests, if you want
      }
    );
    this.interceptors.response.use(
      response => {
        return response;
      },
      error => {
        // Same thing here, set the behavior for onError responses
      }
    );
   }

   cancelOrder (id) {
    return this.put(`/cancel/order/${id}`)
   }

  }
/*
  Here you can choose between exporting the class or a instance of it
  in my case i just want to export the instance with some default config
  and use it, you may ask yourself why that's because i want to centrilize
  the configs on one axios instance instead of multiple instances.
*/
const axiosInstance = new AxiosService({
  // You may want to set this so axios automatically parse your data to a object.
  transformResponse: res => { 
    return JSON.parse(res);
  },
  transformRequest: req => {
    return JSON.stringify(req);
  },
  headers: { 
    "Access-Control-Allow-Origin": "true",
    'Content-Type': 'application/json'
 },
});

export { axiosInstance };

Disclaimer: think really well before going into this implementation because 99% of axios default configs, functions, helpers, etc will not be attached to this instance so you will have to insert them manually like we did when we instanciated a axiosService. But if all of axios stuff doesnt matter for you and you want to create a instance from scratch or even a basic instance to be used in some especific places feel free to do it. So most of times just import axios from "axios" and use axios.create.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM