Files
frontend/lib/api/client.ts
T
Thanh Quy - wolf 37a6ed58c9 Connect backend
2026-04-19 17:04:07 +07:00

56 lines
1.2 KiB
TypeScript

const BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL ?? "";
export class ApiError extends Error {
status: number;
body: string;
constructor(status: number, body: string, message?: string) {
super(message ?? body ?? `Request failed with status ${status}`);
this.name = "ApiError";
this.status = status;
this.body = body;
}
}
type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
interface RequestOptions {
method?: HttpMethod;
body?: unknown;
headers?: Record<string, string>;
signal?: AbortSignal;
}
export async function apiRequest<T = unknown>(
path: string,
options: RequestOptions = {},
): Promise<T> {
const { method = "GET", body, headers = {}, signal } = options;
const res = await fetch(`${BASE_URL}${path}`, {
method,
credentials: "include",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
...headers,
},
body: body !== undefined ? JSON.stringify(body) : undefined,
signal,
});
const rawText = await res.text();
if (!res.ok) {
throw new ApiError(res.status, rawText);
}
if (!rawText) return undefined as T;
try {
return JSON.parse(rawText) as T;
} catch {
return rawText as unknown as T;
}
}