HI! In the new Ultimate React part2 course in lecture 28 Mosh teaches us to create a reusable API Client Class from Axios Instance, and then we export that class. Then we import & create an instance of that class, wherever we wish to use it, and then we use that instance’s getall() method. to get the promise().
`code` api-client.ts
import axios, { AxiosRequestConfig } from "axios";
export interface FetchResponse<T> {
count: number;
results: T[];
}
const axiosInstance = axios.create({
baseURL: "https://api.rawg.io/api",
params: {
key: import.meta.env.VITE_apiKey,
},
});
class APIClient<T> {
endpoint: string;
constructor(endpoint: string) {
this.endpoint = endpoint;
}
getAll = (config: AxiosRequestConfig) => {
return axiosInstance
.get<FetchResponse<T>>(this.endpoint, config)
.then((res) => res.data.results);
};
}
export default APIClient;
and then we use it in this way:-
`code` useGames.ts
import { useQuery } from "@tanstack/react-query";
import { GameQuery } from "../App";
import APIClient from "../services/api-client";
import { Platform } from "./usePlatforms";
const apiClient = new APIClient<Game>("/games");
export interface Game {
id: number;
name: string;
background_image: string;
parent_platforms: { platform: Platform }[];
metacritic: number;
rating_top: number;
}
const useGames = (gameQuery: GameQuery) =>
useQuery<Game[], Error>({
queryKey: ["games", gameQuery],
queryFn: () =>
apiClient.getAll({
params: {
genres: gameQuery.genre?.id,
parent_platforms: gameQuery.platform?.id,
ordering: gameQuery.sortOrder,
search: gameQuery.searchText,
},
}),
});
I was wondering may be instead of this we can define a fn in api-client.ts which uses axiosInstance to fetch and return promise and just export it. Like this:-
`code` api-client.ts
export const axiosFnFetch = <T>(url: string, config?: AxiosRequestConfig) => {
return axiosInstance
.get<FetchResponse<T>>(url, config)
.then((res) => res.data.results);
};
and use it in useGames.ts in this way:-
`code`
const useGames = (gameQuery: GameQuery) =>
useQuery<Game[], Error>({
queryKey: ["games", gameQuery],
queryFn: () =>
axiosFnFetch("/games", {
params: {
genres: gameQuery.genre?.id,
parent_platforms: gameQuery.platform?.id,
ordering: gameQuery.sortOrder,
search: gameQuery.searchText,
},
}),
});
While creating this I noticed one thing that if we create a class we are essentially future-proofing our selves as we can add additional methods depending on future use cases. Since it will all be available in a class it will be convenient to use.
Let me know what are your thoughts on this?