Reputation: 1219
I'm trying to learn vue.js so I made a little app that displays news articles from an API and, in another view, allows the user to log into another server.
For this I'm using Axios. I know I got it to work pretty well at some point, but today when starting my project, it's just impossible to get both apis to work simultaneously.
Here is my login service:
import axiosTrainingAPI from 'axios'
axiosTrainingAPI.defaults.baseURL = 'https://api.example.com'
const trainingAPI = {
login (credentials) {
return new Promise((resolve, reject) => {
axiosTrainingAPI.post('/services/auth.php', credentials)
.then(response => {
resolve(response.data)
}).catch(response => {
reject(response.status)
})
})
}
}
export default trainingAPI
Here is my news service:
import axiosGoogleNewsAPI from 'axios'
axiosGoogleNewsAPI.defaults.baseURL = 'https://newsapi.org'
const googleNewsAPI = {
getPosts (newsId) {
return new Promise((resolve, reject) => {
axiosGoogleNewsAPI.get(`/v2/everything?q=${newsId}&sortBy=publishedAt&apiKey=***********`)
.then(response => {
resolve(response.data)
}).catch(response => {
reject(response.status)
})
})
}
}
export default googleNewsAPI
Both those services are in different JS files and are imported in different vue files but it seems that now they cannot coexist and there is always one overwriting the baseURL of the other (not always the same) almost like if the Axios instance was the same in both cases. So some time the first service uses the second one's baseURL, sometimes it's the second that uses the first one's baseURL...
I don't know exactly the scope of 'import' because it's pretty new to me but both instances are in different files, have different names so I don't really understand how they get mixed up. Except if 'import' always calls the same instance of a module but then how do I work with 2 apis? And why did it work yesterday... I'm confused.
Upvotes: 44
Views: 73874
Reputation: 71
Yea, for clarity:
let config = {baseURL: 'https://some-domain.example/api/',
timeout: 1000,
headers: {
'X-Custom-Header': 'foobar',
'Authorization' : `Bearer ${auth.token}` //where applicable
}
};
let instance = axios.create(config);
Also, You can specify config defaults that will be applied to every request.
axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-
urlencoded';
Upvotes: 7
Reputation: 549
You can simply use multiple instances of Axios with each having its own configuration. For example,
import axios from "axios";
// For common config
axios.defaults.headers.post["Content-Type"] = "application/json";
const mainAxios = axios.create({
baseURL: 'https://some-domain.example/api/'
});
const customAxios = axios.create({
baseURL: 'https://some-custom-domain.example/api/'
});
export {
mainAxios,
customAxios
};
Upvotes: 47
Reputation: 14677
You'll want to create a new instance of Axios with a custom config for each API you want that has a distinct baseURL
.
var instance = axios.create({
baseURL: 'https://example.com/api/',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});
Upvotes: 60
Reputation: 437
I had the same question and to solve it, I created an interface and a function (Example in TS):
export function createClient(baseURL: string) {
return axios.create({
baseURL: baseURL,
headers: { "Content-Type": "application/json" }
});
}
export interface ConfigurableApi {
configure(config: Configuration);
}
And for every client, I created a class
@Singleton()
export class ApiOfClientA implements ConfigurableApi {
client!: AxiosInstance;
configure(config: Configuration) {
this.client = createClient(config.baseURL);
}
...
}
If you want to use JS, you can probably do something like:
import axios from "axios";
let clientA;
const ClientA = {
init(baseURL) {
clientA = axios.create({
baseURL: `${baseURL}`,
headers: {"Content-Type": "application/json"}
});
},
...
};
export {ClientA};
and then just import it in the file you need to use it:
import {ClientA} from "./api/client-a";
Upvotes: 4