Cache a response in Vercel using SSR and serverless functions in SvelteKit
Tags: svelte, ssr, vercel, javascript
Published: 2022-05-13 16:16:27

##TLDR
I will show how we can cache the response of an API using [Vercel](https://vercel.com/) caching and a serverless function (function that is executed during Server Side Rendering in this case and not on client). In this case of the BTCUSD price obtained from a call to the Binance API.

##Introduction
Hello and welcome to my second post. Today, I will show you how we can cache the response of a function that runs on the server ([Vercel](https://vercel.com/) in this case) to optimize the number of calls this functiom does to an external API. This means that the API call will be done on the server and not on client, reducing the payload of the user accessing the website.

##Application
Let's suppose we have a website that everytime is rendered it fetches the price of Bitcoin from the Binance API. This means that everytime a user accesses our site, it fetches data from the Binance API. If we have 100 visits in 1 minute, from visit 50th on, the user will get a `429 HTTP ERROR` (too many requests). Is it needed to call the API multiple times to obtain BTCUSD price which will barely change during those seconds? - Probably not.

So let's see how we can solve this by caching the BTCUSD price on [Vercel](https://vercel.com/). Let's suppose we have 3 clients that access our website, the first one will be the one that calls the serverless function and caches the response for that function for 3600seconds.
![What we're attempting to do](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/azdtz8fl5m2b2sme0hoq.png)

##Code
In this case we only want to cache the response if we actually get a price number from the Binance API. We can use `bodyShouldBeCacheable` or any other valid method.

```ts
// src/routes/api/btcusd.ts
import type { RequestHandler } from '@sveltejs/kit'

const BTCUSDT= 'https://api1.binance.com/api/v3/ticker/price?symbol=BTCUSDT'

export const get: RequestHandler = async () => {
    const getBtcUsdtPrice = async (): Promise<number | undefined> => {
         try{
             const data = await fetch(BTCUSDT)
             const { price } = await data.json()
             return price
         } catch(err) {
             return undefined
         }
    }

    const body = await getBtcUsdtPrice()
    const bodyShouldBeCacheable = !isNaN(body)

    return {
        status: 200,
        body,
        headers: {
            'Cache-Control': bodyShouldBeCacheable 
             ? 'max-age=3600, public' 
             : 'no-cache',
        },
    }
}

```

```ts
// src/routes/index.svelte

const btcPrice: Writable<number> = writable(0)

const fetchAndUpdateExchanges = async () => {
    const response = await fetch('/api/exchanges')
    const btcPriceData= await response.json()
    btcPrice.set(btcPriceData)
}
```

##Conclusion
Using SSR is always good choice to reduce the amount of data the end user is downloading to render your site, specially if running on mobile phone with limited data to use, or slow connections.
On the other hand [Vercel](https://vercel.com/) will not let you render data on server for free (completely) forever, so, caching a response will also aid your pocket!

You can follow me on:

- [Github ](https://github.com/aspnxdd)