In my opinion, a more efficient design strategy involves creating methods with specific names rather than relying on a generic method. Each function name should clearly indicate its purpose, enhancing specificity. Below is the design I would recommend:
class ApiService {
// method to fetch states from the API call
private static fetchState(url: string, options: StateOptions): Promise<State[]> {
return ApiService.fetchData(url, options);
}
// private method, only accessible in ApiService class
private static async fetchData(url: string, options?: any): Promise<any> {
const res = await fetch(url, options);
const data = await res.json();
return data;
}
}
It is advisable not to consolidate all API calls within a single class; you can categorize them by extending the APIService
class and by defining the fetchData
method as protected
.
The advantages of this approach include:
- Defining interfaces for options and return types
- Function names directly correspond to the API call, aiding in debugging and code readability
- Catering to special cases like data preprocessing or constant definitions within specific functions. For instance, if a language parameter like
en
is required for the state API call, it's preferable to hardcode it in the ApiService.fetchState
method rather than passing it as an argument with every function call.
I have opted for an object-oriented approach, but you can also implement the same functionality using a functional approach. The key principle is to avoid relying on a generic method throughout your codebase, as it can lead to scalability issues and complex maintenance.
This recommendation is based on my personal experience.
Addressing your query:
How to create a Function that returns a Promise type dynamically?
You can achieve this using generics in TypeScript.
async function fetchData<T>(url: string): Promise<T> {
const result: any = {};
return result;
}
interface State {
code: string;
name: string;
}
interface Country {
code: string;
name: string;
}
const fetchStates = fetchData<State[]>("/fetch/state");
const fetchCountry = fetchData<Country[]>("/fetch/country");
Link to TS Playground