Skip to content

Instantly share code, notes, and snippets.

@nathanchase
Last active March 7, 2024 02:34
Show Gist options
  • Select an option

  • Save nathanchase/6440bf72d34c047498edcd4f35c15e2a to your computer and use it in GitHub Desktop.

Select an option

Save nathanchase/6440bf72d34c047498edcd4f35c15e2a to your computer and use it in GitHub Desktop.

Revisions

  1. nathanchase revised this gist Aug 20, 2022. 1 changed file with 3 additions and 6 deletions.
    9 changes: 3 additions & 6 deletions [...].ts
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,5 @@
    Here's my current implementation of a Nuxt 3 server API catch-all with caching, retries, and request/response logging with total elapsed time:

    ```js
    // /server/api/[...].ts
    // 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';
    @@ -86,5 +84,4 @@ export default defineEventHandler(async event => {
    // 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);
    });
    ```
    });
  2. nathanchase renamed this gist Aug 20, 2022. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  3. nathanchase created this gist Aug 20, 2022.
    90 changes: 90 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,90 @@
    Here's my current implementation of a Nuxt 3 server API catch-all with caching, retries, and request/response logging with total elapsed time:

    ```js
    // /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);
    });
    ```