aboutsummaryrefslogtreecommitdiffstats
path: root/thallium-frontend/src
diff options
context:
space:
mode:
authorGravatar Joe Banks <[email protected]>2024-08-19 17:05:24 +0100
committerGravatar Joe Banks <[email protected]>2024-08-19 17:05:24 +0100
commitdf35284987d7b9e04e76bad44bc529f45febf38f (patch)
treec8e1cd836f1e721ac97070f0fc98f6f5d605d6ad /thallium-frontend/src
parentBuild in API base URL (diff)
Add API client
Diffstat (limited to 'thallium-frontend/src')
-rw-r--r--thallium-frontend/src/api/client.ts53
1 files changed, 53 insertions, 0 deletions
diff --git a/thallium-frontend/src/api/client.ts b/thallium-frontend/src/api/client.ts
new file mode 100644
index 0000000..9e64af5
--- /dev/null
+++ b/thallium-frontend/src/api/client.ts
@@ -0,0 +1,53 @@
+/*
+TODO: Someday these methods should try pick out authentication from the Redux stores.
+*/
+
+const BASE_URL = THALLIUM_BASE_URL;
+
+interface APIErrorResponse {
+ detail?: string;
+}
+
+export type APIRequestBody = Record<string, unknown>;
+
+type APIResponseBody = Record<string, unknown>;
+
+export class APIError extends Error {
+ constructor(message: string, public status: number, public data: APIErrorResponse | null) {
+ super(message);
+ }
+}
+
+const request = async (url: string, options: RequestInit = {}): Promise<APIResponseBody> => {
+ const response = await fetch(`${BASE_URL}${url}`, options);
+ if (!response.ok) {
+ let maybeData: APIErrorResponse | null;
+
+ try {
+ maybeData = await response.json() as APIErrorResponse;
+ } catch (e) {
+ maybeData = null;
+ }
+
+ throw new APIError(response.statusText, response.status, maybeData);
+ }
+ return response.json() as Promise<APIResponseBody>;
+};
+
+export const get = async (url: string, options: RequestInit = {}): Promise<APIResponseBody> => {
+ return request(url, {
+ ...options,
+ method: "GET",
+ });
+};
+
+export const post = async (url: string, data: APIRequestBody, options: RequestInit = {}): Promise<APIResponseBody> => {
+ return request(url, {
+ ...options,
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(data),
+ });
+};