Skip to content

Instantly share code, notes, and snippets.

@nathanchase
Last active March 7, 2024 02:34
Show Gist options
  • Save nathanchase/6440bf72d34c047498edcd4f35c15e2a to your computer and use it in GitHub Desktop.
Save nathanchase/6440bf72d34c047498edcd4f35c15e2a to your computer and use it in GitHub Desktop.
Nuxt 3 Server API catch-all w/ caching, retries, and request/response logging (with total elapsed time)
// Here's my current implementation of a Nuxt 3 server API catch-all with caching, retries, and request/response logging with total elapsed time:
// Place in: /server/api/[...].ts
import LRU from 'lru-cache';
import { getCookie } from 'h3';
const config = useRuntimeConfig();
const cache = new LRU({
max: 100,
ttl: 1000 * 60 * 60, // One hour
});
export default defineEventHandler(async event => {
let startTime: number;
let duration: number;
const abortController = new AbortController();
let timer = null;
const method = useMethod(event);
const params = useQuery(event);
const body = method === 'GET' ? undefined : await useBody(event);
const token = getCookie(event, 'auth._token.local');
if (!cache.get(event.req.url)) {
const response = $fetch(event.req.url, {
baseURL: config.baseUrl,
params,
method,
body,
retry: 10,
signal: abortController.signal,
headers: {
Authorization: `${token}`,
},
// Log request
async onRequest({ request, options }) {
timer = setTimeout(() => {
abortController.abort();
console.log(`Retrying request to: ${request}`);
}, 2500); // Abort request in 2.5s.
startTime = new Date().getTime();
options.headers = new Headers(options.headers);
options.headers.set('starttime', `${new Date().getTime()}`);
await console.log(
`%c[${new Date().toLocaleTimeString()}] %cSSR-Request: %c${request}`,
'color: gray',
'color: orange',
'color: white',
);
},
// Log response
async onResponse({ request, response }) {
if (timer) {
clearTimeout(timer); // clear timer
}
const currentTime = new Date().getTime();
duration = currentTime - startTime;
await console.log(
`✔️%cSSR-Response: ${request} - ${response.status} %c(${duration}ms)`,
'color: orange',
'color: white',
);
},
// Log error
async onResponseError({ error }) {
await console.error('%cSSR-Error', error,
'color: white; background: red;',
);
},
});
// Set response to cache
cache.set(event.req.url, response);
return response;
}
// Log a cache hit to a given request URL
console.log(`%c[SSR] Cache hit: ${event.req.url}`, 'color: orange');
return cache.get(event.req.url);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment