Home > database >  VueJS AXIOS - Is it correct to create an axios instance for every single request?
VueJS AXIOS - Is it correct to create an axios instance for every single request?

Time:09-23

I've built a VueJS application that uses Vue-Axios to communicate with a Laravel API.

In my project, I have an api.js file that contains the following code:

import axios from "axios";

export function apiRequestProtocol(token = null) {
    var api_instance = axios.create({
        baseURL: "http://127.0.0.1:8000/api/",
    });

    if (token) {
        api_instance.interceptors.request.use(
            (config) => {
              config.headers.Authorization = `Bearer ${token}`;
              return config;
            },
            (error) => {
              return Promise.reject(error);
            }
        );
    } 
    return api_instance;
}

The apiRequireProtocol function is imported in every Vue Component that needs to make a request to the Laravel API.

As you can see, every time a component uses apiRequestProtocol(), a new Axios instance is created.

I made this in this way because some "requests" from Axios needs access_token, and others don't.

I had tried using the same Axios instance for every single request just changing its header, but I couldn't do it successfully. If you know how to use only one instance changing it depending on the request (if needs token or don't), please let me know how.

Furthermore, I would like to know if I should "delete" these instances after using them or if there is even a better way to do this.

Thank you!

My package.json:

{
  ...
  "dependencies": {
    "@vueuse/head": "^0.6.0",
    "axios": "^0.21.1",
    "core-js": "^3.6.5",
    "vue": "^3.0.0",
    "vue-axios": "^3.2.5",
    "vue-router": "^4.0.0-0",
    "vuex": "^4.0.0-0",
    "vuex-persistedstate": "^4.1.0"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-router": "~4.5.0",
    "@vue/cli-plugin-vuex": "~4.5.0",
    "@vue/cli-service": "~4.5.0",
    "@vue/compiler-sfc": "^3.0.0",
    "sass": "^1.26.5",
    "sass-loader": "^8.0.2"
  }
}

CodePudding user response:

Multiple instances

No you definitely don't want an axios instance for every connection! But you might want multiple instances. Specifically, I would use plain axios.get for unauthenticated requests, and an instance for every different token in the app. That way I don't have to mess around with adding and removing interceptors.

Plain axios requests with headers

Can be done without anything fancy at all:

axios.get(URL, {headers: {"X-my-custom-header": "my-custom-val"}})

Token Authentication with different headers

can be done the same way:

var token_axios = axios.create({ BaseURL: "http://exam.pl" })
var token_interceptor = token_axios.intercepters.request.use(
  config => {
    config.headers.Authorization = "Token: MYTOKEN"
    return config
  },
  error => {
    return Promise.reject(error)
  }
)
token_axios.get(url, {headers: {"x-my-custom-header": "abc"}})

Overriding Token

can be done exactly the same we we set it originally, and

removing interceptor

can be done if we create or get a reference to it first:

token_axios.interceptors.request.eject(token_interceptor)

(note we saved the reference from above).

Whilst you could use the use/eject paradigm to modify one instance every time, and this would be the right approach if tokens changed frequently and requests were rare, if (as I suspect) tokens change infrequently and requests are common, I would simply use a few objects as described above.

To answer your other question, whilst JS has garbage collection, if you were creating dozens of throwaway objects, deleting them manually is good practice as the garbage collector causes unpredictable slowdowns when it is called.

References

https://axios-http.com/docs/interceptors

  • Related