Peeking digits of π with serverless function

March 14, 2023

Happy π\pi day everybody! I’m going to show you how to use serverless functions to build an API for find digits in π\pi. It may not the most useful use case for the serverless functions, but it’s a fun one. More importantly, you can see the API in action with an embedded π\pi finder in my blog below. Just type in any sequences in the form to find their positions among the first one million digits in π\pi.

The post is insipred by Coding Challenge #156: Peeking Inside Pi from The Coding Train.

Why serveless function?

Some of you may think why don’t let the client side do the calculation. Well, it could be a good idea, but that solution could not sccale well. In order to that, we first need to load a file containing the π\pi digits into the client side. It could work for a small number of digits like 1000 or 10000 digits because the file size is relatively small. However, as the number of digits increases, the file size also increases. Letting our browswer to load such a large file and consume the memory space is not a good idea.

Another approach is to offload the work to the server side by writing a simple API to query the digits. This approach is much better than the previous one, and more flexibile with scalability. Hosting one simple API with on a separate server is maybe to much for a small project. Since this site is deployed in Vercel, we can could levarage and implement our API with their serverless functions.

Before we start

Before we start, we need to have a file containing the digits of π\pi. I have a file called pi-million.txt containing the first million digits of π\pi. Also, make sure you have a Vercel account and have installed the Vercel CLI in your machine. To test the API locally, we need to run the command vercel dev in the root directory of our project.

How to implement the API

First, we need to create a folder called api in the root directory of our project. Our API endpoint will be api/pi-peek/[number], where [number] is any query number. So, we need to create a file called pi-peek/[number].ts in the api folder. Also, we need to have a file contained the digits of π\pi and called pi-million.txt in the api/pi-peek folder.

[number].ts
import type { VercelRequest, VercelResponse } from "@vercel/node";
import { readFileSync } from "fs";
import path from "path";
 
const FILE = "pi-million.txt";
const PATH = path.join(process.cwd(), "api", "pi-peek", FILE);
const RANGE = 5;
 
const pi = readFileSync(PATH, "utf-8");
 
export default function handler(
  request: VercelRequest,
  response: VercelResponse
) {
  const number = request.query.number as string;
  const index = pi.indexOf(number);
  if (index < 0) {
    response.status(200).send({
      index: -1,
      before: "",
      between: "",
      after: pi.slice(0, RANGE)
    });
    return;
  }
 
  response.status(200).send({
    index: index == 0 ? index : index - 1,
    before: pi.slice(index - RANGE < 0 ? 0 : index - RANGE, index),
    between: number,
    after: pi.slice(index + number.length, index + number.length + RANGE)
  });
}

Now, we can connect the API to our client side just by calling the endpoint with the query number.

type Response = {
  index: number
  before: string
  middle: string
  after: string
}
 
const peek = async (number: string) => {
  const response = await fetch(`/api/pi-peek/${number}`)
  return await response.json() as Response
}

Now, it’s your choice to build the UI can connect to the API. In this case, I choose to use Svelte to build the UI. You can see the result in the embedded π\pi finder in my blog above.