mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
* 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
54 lines
1.7 KiB
TypeScript
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);
|
|
}
|
|
}
|