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.
AWS lambda
Google Cloud Functions
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