type ApiClientConstructor = {
baseURL: string;
authToken: string | null;
};
class APIClient {
baseURL: string;
authToken: string | null;
constructor({ baseURL, authToken }: ApiClientConstructor) {
this.baseURL = baseURL;
this.authToken = null;
}
addAuthToken(token: string) {
this.authToken = token;
}
async request<T>(url: string, options: RequestInit) {
const response = await fetch(`${this.baseURL}${url}`, options);
if (!response.ok) {
const error = new Error('HTTP Error', {
cause: response.statusText,
});
throw error;
}
return response.json() as Promise<T>;
}
get<T>(url: string, signal: AbortSignal | null = null) {
return this.request<T>(url, {
method: 'GET',
signal: signal,
headers: {
'Content-Type': 'application/json',
},
});
}
post<T, B>(url: string, data: B, signal: AbortSignal | null = null) {
return this.request<T>(url, {
method: 'POST',
signal: signal,
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
}
put<T, B>(url: string, data: B, signal: AbortSignal | null = null) {
return this.request<T>(url, {
method: 'PUT',
signal: signal,
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
}
delete<T>(url: string, signal: AbortSignal | null = null) {
return this.request<T>(url, {
method: 'DELETE',
signal: signal,
headers: {
'Content-Type': 'application/json',
},
});
}
}
export const apiClient = new APIClient({
baseURL: '',
authToken: null,
});
Usage
useEffect(() => {
const controller = new AbortController();
apiClient
.get<RootObject>(
'https://api.restful-api.dev/objects/4',
controller.signal,
)
.then((res) => {
console.log(res);
});
return () => {
controller.abort();
};
}, []);