diff --git a/backend/src/services/External/HitphoneServices/ClientExists.ts b/backend/src/services/External/HitphoneServices/ClientExists.ts new file mode 100644 index 0000000..d17841b --- /dev/null +++ b/backend/src/services/External/HitphoneServices/ClientExists.ts @@ -0,0 +1,32 @@ +import { cache } from "./utils/cache"; +import authConfig from "../../../config/auth"; +import { responseOk } from "./utils/fetch"; + +export const fetchWithKey: typeof fetch = async (endpoint, options) => { + const response = await fetch(authConfig.hitphone.CLIENT_SERVICE_URL + endpoint, { + ...options, + headers: { + ...options?.headers, + "X-Api-Key": authConfig.hitphone.CLIENT_SERVICE_API_KEY, + }, + }); + + return response; +}; + +const CLIENT_EXISTS_CACHE_TTL = 10 * 1000 * 60; +const clientExistsCache = cache(CLIENT_EXISTS_CACHE_TTL); + +export const clientExists = async (id: string): Promise => { + const fetcher = async (id: string) => { + const response = await fetchWithKey(`/clients/${id}`, { method: "HEAD" }); + + await responseOk(response); + + return true; + }; + + const exists = await clientExistsCache.get(id, () => fetcher(id)); + + return exists; +}; \ No newline at end of file diff --git a/backend/src/services/External/HitphoneServices/utils/cache.ts b/backend/src/services/External/HitphoneServices/utils/cache.ts new file mode 100644 index 0000000..559b9f0 --- /dev/null +++ b/backend/src/services/External/HitphoneServices/utils/cache.ts @@ -0,0 +1,35 @@ +export const cache = (ttl: number) => { + type Cache = { promise: Promise, timestamp: number }; + const store = new Map(); + + const get = async (key: string, fetcher: () => Promise) => { + if (store.has(key)) { + const cached = store.get(key)!; + + if (Date.now() - cached.timestamp < ttl) { + return cached.promise; + } else { + store.delete(key); + } + } + + try { + const promise = fetcher(); + + store.set(key, { + promise, + timestamp: Date.now() + }); + + return promise; + } catch (error) { + store.delete(key); + + throw error; + } + } + + return { + get + }; +}; \ No newline at end of file diff --git a/backend/src/services/External/HitphoneServices/utils/fetch.ts b/backend/src/services/External/HitphoneServices/utils/fetch.ts new file mode 100644 index 0000000..3495fc1 --- /dev/null +++ b/backend/src/services/External/HitphoneServices/utils/fetch.ts @@ -0,0 +1,17 @@ +export class FetchClientsApiError extends Error { + public statusCode: number; + + constructor(message: string, statusCode: number) { + super(message); + + this.statusCode = statusCode; + this.name = "FetchClientsApiError"; + } +} + +export const responseOk = async (response: Response) => { + if (!response.ok) { + const message = await response.text(); + throw new FetchClientsApiError(message, response.status); + } +}; \ No newline at end of file