Last active
March 7, 2024 02:34
-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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