Files
explore/nextjs/utils/fetchApi.ts
T
tom goriunovandGitHub b6d5268188 Enhance OG tags with API data (#1806)
* simple fetch data for token instance page

* generate enhanced metadata

* group query params in page props

* make base gSSP function generic

* add metric for search engine bots

* measure api request duration

* get API data for token, address and dapp pages

* improve typings for apiData prop

* add ENV variable

* tweak logs for /media-type requests

* [skip ci] add prefix to default metrics
2024-04-16 10:27:47 +02:00

54 lines
1.7 KiB
TypeScript

import fetch, { AbortError } from 'node-fetch';
import buildUrl from 'nextjs/utils/buildUrl';
import { httpLogger } from 'nextjs/utils/logger';
import { RESOURCES } from 'lib/api/resources';
import type { ResourceName, ResourcePathParams, ResourcePayload } from 'lib/api/resources';
import { SECOND } from 'lib/consts';
import metrics from 'lib/monitoring/metrics';
type Params<R extends ResourceName> = (
{
resource: R;
pathParams?: ResourcePathParams<R>;
} | {
url: string;
route: string;
}
) & {
timeout?: number;
}
export default async function fetchApi<R extends ResourceName = never, S = ResourcePayload<R>>(params: Params<R>): Promise<S | undefined> {
const controller = new AbortController();
const timeout = setTimeout(() => {
controller.abort();
}, params.timeout || SECOND);
const url = 'url' in params ? params.url : buildUrl(params.resource, params.pathParams);
const route = 'route' in params ? params.route : RESOURCES[params.resource]['path'];
const end = metrics?.apiRequestDuration.startTimer();
try {
const response = await fetch(url, { signal: controller.signal });
const duration = end?.({ route, code: response.status });
if (response.status === 200) {
httpLogger.logger.info({ message: 'API fetch', url, code: response.status, duration });
} else {
httpLogger.logger.error({ message: 'API fetch', url, code: response.status, duration });
}
return await response.json() as Promise<S>;
} catch (error) {
const code = error instanceof AbortError ? 504 : 500;
const duration = end?.({ route, code });
httpLogger.logger.error({ message: 'API fetch', url, code, duration });
} finally {
clearTimeout(timeout);
}
}