Implementing CRUD with Astro

Implementing a Count-Up Function in Astro

Astro is a modern web framework supporting Static Site Generation (SSG) and Server-Side Rendering (SSR). It integrates with various frameworks such as React, Vue, Svelte, and Solid, making it ideal for building high-performance websites. This article explains how to implement a count-up function combining Astro and Prisma.

1. Project Setup

To introduce Astro to your project, follow these steps:

npm create astro@latest
cd my-astro-counter
npm install
npm install @prisma/client prisma

2. Prisma Setup

Initialize Prisma and define the database schema.

npx prisma init

Next, edit prisma/schema.prisma to define the data model.

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

datasource db {
  provider = "sqlite"
  url      = "file:./dev.db"
}

model Counter {
  id    Int    @id @default(autoincrement())
  count Int    @default(0)
}

Run the migration to create the database.

npx prisma migrate dev --name init

3. Implementing the Count-Up API

Create src/pages/api/counter.ts and implement an API to retrieve and update the count value.

import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient();

export async function GET() {
  let counter = await prisma.counter.findFirst();
  if (!counter) {
    counter = await prisma.counter.create({ data: { count: 0 } });
  }
  return new Response(JSON.stringify(counter), {
    headers: { "Content-Type": "application/json" },
  });
}

export async function POST() {
  const counter = await prisma.counter.findFirst();
  if (!counter) {
    return new Response("Counter not found", { status: 404 });
  }
  const updatedCounter = await prisma.counter.update({
    where: { id: counter.id },
    data: { count: counter.count + 1 },
  });
  return new Response(JSON.stringify(updatedCounter), {
    headers: { "Content-Type": "application/json" },
  });
}

4. Frontend Implementation

Use an Astro component to display the count and allow it to increment with a button click.

src/pages/index.astro

---
import { useState, useEffect } from 'react';

const [count, setCount] = useState(0);

useEffect(() => {
  fetch('/api/counter')
    .then(response => response.json())
    .then(data => setCount(data.count));
}, []);

const handleIncrement = async () => {
  const response = await fetch('/api/counter', { method: 'POST' });
  const data = await response.json();
  setCount(data.count);
};
---

<html>
  <head>
    <title>Astro Counter with Prisma</title>
  </head>
  <body>
    <h1>Counter</h1>
    <p>Count: {count}</p>
    <button onClick={handleIncrement}>Increment</button>
  </body>
</html>

Summary

This article demonstrated how to build a count-up function using Astro and Prisma. Utilizing an API route allows the database and frontend to interact, updating the count each time the button is pressed.