Understanding Serverless Backend Solutions

Understanding Serverless Backend Solutions

The term "serverless" does not mean there are no servers involved in the production. The cloud providers handle the allocation and managing of the servers.

There are many serverless providers.

  1. AWS lambda

  2. Google Cloud Functions

  3. Cloudflare Workers

Why choose serverless architecture?

We can choose serverless backends when we don't want to worry about deployments. When we can't anticipate the incoming traffic to our website serverless architecture can handle auto-scaling.

If the traffic is low this architecture optimizes the cost so that we don't have to pay more.

Let's look at an example using Cloudflare workers.

use npm create cloudflare command to initialize the project.

Next we can start the worker locally. Run npm run dev command

Routing in Cloudflare

// src/index.ts

export default {
    async fetch(request, env, ctx): Promise<Response> {
        console.log(request.body)
        console.log(request.headers)

        if (request.method=="GET"){
            return Response.json({
                message: "This is a get request"
            })
        }else{
            return Response.json({
                message: "This is not a get request"
            })
        }
    },
} satisfies ExportedHandler<Env>;

Let's deploy this worker now.

Use wrangler CLI for logging in to your Cloudflare account.

Use the npx wrangler login command to login to your account. And then press allow.

Then use the npm run deploy command.

Go to the highlighted URL on the browser.

We are getting the Json response.

Issues with Cloudflare workers

We cannot use express with Cloudflare as express heavily relies on node js.

Cloudflare workers don't run on Javascript runtime they have their own runtime.

This is where Hono comes into picture.

Hono

Hono is a simple web application framework similar to Express, without a frontend. But it runs on CDN Edges and allows you to construct larger applications when combined with middleware.

Let's get started with an example.

Use the npm create hono@latest to get started.

// src/index.ts

import { Hono } from 'hono'

const app = new Hono()

app.get('/', (c) => {
  return c.text('Hello Hono!')
})

export default app

Use the npx wrangler login command to login.

Let's create a middleware for authentication.

import { Hono, Next } from 'hono'
import { Context } from 'hono/jsx';

const app = new Hono()

app.use(async (c, next) => {
  if (c.req.header("Authorization")) {
    await next()
  } else {
    return c.text("You dont have acces");
  }
})

app.get('/', async (c) => {
  const body = await c.req.parseBody()
  console.log(body);
  console.log(c.req.header("Authorization"));
  console.log(c.req.query("param"));

  return c.json({msg: "Signed"})
})

export default app

Connecting To Prisma DB

Add Prisma to your project. Run npm install --save-dev prisma command followed by npx prisma init.

// prisma/schema.prisma

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = "prisma_url"

}

model User{
  id Int @id @default(autoincrement())
  firstname String
  lastname String
  email String 
  password String @unique
}

Run npx prisma migrate dev User init command.

Then go to Prisma accelerate and generate an api key. Place that api key in .env file.

Add accelerate dependencies using npm install @prisma/extension-accelerate . Next use

npx prisma generate --no-engine .

Modify your index.ts file.

import { Hono, Next } from 'hono'
import { PrismaClient } from '@prisma/client/edge'
import { withAccelerate } from '@prisma/extension-accelerate'
import { env } from 'hono/adapter'

const app = new Hono()

app.post('/', async (c) => {

  const body: {
    firstname: string;
    lastname: string;
    email: string
    password: string
  } = await c.req.json()
  const { DATABASE_URL } = env<{ DATABASE_URL: string }>(c)

  const prisma = new PrismaClient({
      datasourceUrl: "PRISMA_ACCELERATE_URL",
  }).$extends(withAccelerate())

  console.log(body)

  await prisma.user.create({
    data: {
      firstname: body.firstname,
      lastname: body.lastname,
      email: body.email,
      password: body.password
    }
  })

  return c.json({msg: "Account Created"})
})

export default app

Did you find this article valuable?

Support Reuben's blog by becoming a sponsor. Any amount is appreciated!