generic functions for backend queries
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
import axios, { AxiosInstance, AxiosRequestConfig } from "axios";
|
||||
import { getTokenCookie } from "@utils/auth";
|
||||
|
||||
export const HOST = `${process.env.NEXT_PUBLIC_API_URL}`;
|
||||
|
||||
const axiosInstance: AxiosInstance = axios.create({
|
||||
baseURL: process.env.NEXT_PUBLIC_API_URL,
|
||||
});
|
||||
|
||||
export enum APIPath {
|
||||
TAGS = "/tags/:id",
|
||||
EVENTS = "/events/:id",
|
||||
FEED = "/feed/:id",
|
||||
JOBADS = "/jobads/:id",
|
||||
SIGNUPS = "/signup/:id",
|
||||
SIGNUP_FORMS = "/signupForm/:id",
|
||||
AUTH_TOKEN = "/api-token-auth",
|
||||
AUTH_TOKEN_VERIFY = "/api-token-verify",
|
||||
}
|
||||
|
||||
export type API = {
|
||||
path: APIPath;
|
||||
urlParams?: {
|
||||
id?: string | number;
|
||||
};
|
||||
queryParams?: {
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
since?: Date;
|
||||
};
|
||||
authenticated?: boolean;
|
||||
};
|
||||
|
||||
type Headers = {
|
||||
Authorization?: string;
|
||||
};
|
||||
|
||||
const getAuthHeader = (): string => {
|
||||
const jwt = getTokenCookie();
|
||||
return `JWT ${jwt}`;
|
||||
};
|
||||
|
||||
const getHeaders = (auth?: boolean): Headers => {
|
||||
if (auth) {
|
||||
return {
|
||||
Authorization: getAuthHeader(),
|
||||
};
|
||||
}
|
||||
return {};
|
||||
};
|
||||
|
||||
const fillUrlParams = (apiPath: APIPath, params: API["urlParams"] = {}): string => {
|
||||
const path = apiPath
|
||||
.split("/")
|
||||
.filter(Boolean)
|
||||
.map((urlComponent) => {
|
||||
// fill in each placeholder component like ':id' with value from params
|
||||
if (urlComponent.startsWith(":")) {
|
||||
const key = urlComponent.substring(1);
|
||||
const value = params[key];
|
||||
return value;
|
||||
}
|
||||
return urlComponent;
|
||||
})
|
||||
.join("/");
|
||||
// code above strips leading '/' from path
|
||||
return `/${path}`;
|
||||
};
|
||||
|
||||
async function callBackendAPI<RequestType, ResponseType>(
|
||||
path: APIPath,
|
||||
urlParams: API["urlParams"] = {},
|
||||
queryParams: API["queryParams"] = {},
|
||||
method: AxiosRequestConfig["method"],
|
||||
headers: Headers,
|
||||
requestBody: RequestType,
|
||||
): Promise<ResponseType> {
|
||||
const url = fillUrlParams(path, urlParams);
|
||||
const request: AxiosRequestConfig = {
|
||||
url,
|
||||
method,
|
||||
headers,
|
||||
params: queryParams,
|
||||
data: requestBody,
|
||||
responseType: "json",
|
||||
};
|
||||
const response = await axiosInstance.request<ResponseType>(request);
|
||||
|
||||
const arrayResp = (response.data as { results?: ResponseType });
|
||||
if (Array.isArray(arrayResp.results)) {
|
||||
return arrayResp.results;
|
||||
}
|
||||
return response.data;
|
||||
}
|
||||
|
||||
export async function getBackendAPI<ResponseType>({
|
||||
path, urlParams, queryParams, authenticated,
|
||||
}: API): Promise<ResponseType> {
|
||||
const headers = getHeaders(authenticated);
|
||||
return callBackendAPI<undefined, ResponseType>(path, urlParams, queryParams, "GET", headers, undefined);
|
||||
}
|
||||
|
||||
export async function postBackendAPI<RequestType, ResponseType>({
|
||||
path, urlParams, queryParams, authenticated,
|
||||
}: API, body: RequestType): Promise<ResponseType> {
|
||||
const headers = getHeaders(authenticated);
|
||||
return callBackendAPI<RequestType, ResponseType>(path, urlParams, queryParams, "POST", headers, body);
|
||||
}
|
||||
|
||||
export async function putBackendAPI<RequestType, ResponseType>({
|
||||
path, urlParams, queryParams, authenticated,
|
||||
}: API, body: RequestType): Promise<ResponseType> {
|
||||
const headers = getHeaders(authenticated);
|
||||
return callBackendAPI<RequestType, ResponseType>(path, urlParams, queryParams, "PUT", headers, body);
|
||||
}
|
||||
|
||||
export async function deleteBackendAPI<ResponseType>({
|
||||
path, urlParams, queryParams, authenticated,
|
||||
}: API): Promise<ResponseType> {
|
||||
const headers = getHeaders(authenticated);
|
||||
return callBackendAPI<undefined, ResponseType>(path, urlParams, queryParams, "DELETE", headers, undefined);
|
||||
}
|
||||
+25
-43
@@ -1,11 +1,10 @@
|
||||
/* eslint-disable no-console */
|
||||
import axios from "axios";
|
||||
import Event from "@models/Event";
|
||||
import { getAuthHeader } from "@utils/auth";
|
||||
import {
|
||||
APIPath, deleteBackendAPI, getBackendAPI, postBackendAPI, putBackendAPI,
|
||||
} from "./backend";
|
||||
|
||||
export const URL = `${process.env.NEXT_PUBLIC_API_URL}/events/`;
|
||||
|
||||
export interface Options {
|
||||
interface Options {
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
auth?: boolean;
|
||||
@@ -15,33 +14,28 @@ export interface Options {
|
||||
class EventApi {
|
||||
static async getEvent(id: number, auth = false): Promise<Event> {
|
||||
try {
|
||||
const headers = auth ? { Authorization: getAuthHeader() } : null;
|
||||
const resp = await axios.get(`${URL}${id}/`, {
|
||||
headers,
|
||||
return await getBackendAPI({
|
||||
path: APIPath.EVENTS, urlParams: { id }, authenticated: auth,
|
||||
});
|
||||
return resp.data;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
static async getEvents(options: Options = {}): Promise<Event[]> {
|
||||
const {
|
||||
since, limit, offset, auth,
|
||||
} = options;
|
||||
static async getEvents({
|
||||
since, limit, offset, auth,
|
||||
}: Options = {}): Promise<Event[]> {
|
||||
try {
|
||||
const params = {
|
||||
since,
|
||||
limit,
|
||||
offset,
|
||||
};
|
||||
const headers = auth ? { Authorization: getAuthHeader() } : null;
|
||||
const resp = await axios.get(`${URL}`, {
|
||||
headers,
|
||||
params,
|
||||
return await getBackendAPI<Event[]>({
|
||||
path: APIPath.EVENTS,
|
||||
queryParams: {
|
||||
since,
|
||||
limit,
|
||||
offset,
|
||||
},
|
||||
authenticated: auth,
|
||||
});
|
||||
return resp.data.results;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
throw err;
|
||||
@@ -50,12 +44,9 @@ class EventApi {
|
||||
|
||||
static async createEvent(data: Event): Promise<Event> {
|
||||
try {
|
||||
const resp = await axios.post(URL, data, {
|
||||
headers: {
|
||||
Authorization: getAuthHeader(),
|
||||
},
|
||||
});
|
||||
return resp.data;
|
||||
return await postBackendAPI<Event, Event>({
|
||||
path: APIPath.EVENTS, authenticated: true,
|
||||
}, data);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
throw err;
|
||||
@@ -64,27 +55,18 @@ class EventApi {
|
||||
|
||||
static async updateEvent(data: Event): Promise<Event> {
|
||||
try {
|
||||
const putUrl = `${URL}${data.id}/`;
|
||||
const resp = await axios.put(putUrl, data, {
|
||||
headers: {
|
||||
Authorization: getAuthHeader(),
|
||||
},
|
||||
});
|
||||
return resp.data;
|
||||
return await putBackendAPI<Event, Event>({
|
||||
path: APIPath.EVENTS, urlParams: { id: data.id }, authenticated: true,
|
||||
}, data);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
static async deleteEvent(id: number) {
|
||||
static async deleteEvent(id: number): Promise<void> {
|
||||
try {
|
||||
const resp = await axios.delete(`${URL}${id}`, {
|
||||
headers: {
|
||||
Authorization: getAuthHeader(),
|
||||
},
|
||||
});
|
||||
return resp.data;
|
||||
await deleteBackendAPI<{ message: "OK" }>({ path: APIPath.EVENTS, urlParams: { id } });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
throw err;
|
||||
|
||||
Reference in New Issue
Block a user