DEV Community

Alex Spinov
Alex Spinov

Posted on

Astro DB Has a Free API You're Not Using

Astro DB is a fully-managed SQL database built into Astro. It's powered by LibSQL (Turso) and gives you type-safe database access with zero configuration.

The Free APIs You're Missing

1. Schema Definition — TypeScript-First

// db/config.ts
import { defineDb, defineTable, column } from "astro:db";

const Post = defineTable({
  columns: {
    id: column.number({ primaryKey: true }),
    title: column.text(),
    slug: column.text({ unique: true }),
    content: column.text(),
    published: column.boolean({ default: false }),
    authorId: column.number({ references: () => Author.columns.id }),
    createdAt: column.date({ default: new Date() }),
  },
});

const Author = defineTable({
  columns: {
    id: column.number({ primaryKey: true }),
    name: column.text(),
    email: column.text({ unique: true }),
  },
});

export default defineDb({ tables: { Post, Author } });
Enter fullscreen mode Exit fullscreen mode

Full type inference from schema. No codegen step.

2. Seeding — Type-Safe Data Loading

// db/seed.ts
import { db, Post, Author } from "astro:db";

export default async function seed() {
  await db.insert(Author).values([
    { id: 1, name: "Alice", email: "alice@example.com" },
    { id: 2, name: "Bob", email: "bob@example.com" },
  ]);

  await db.insert(Post).values([
    { id: 1, title: "Hello Astro DB", slug: "hello-astro-db", content: "...", authorId: 1 },
  ]);
}
Enter fullscreen mode Exit fullscreen mode

3. Drizzle-Powered Queries — Full SQL Power

import { db, Post, Author, eq, desc, like, sql } from "astro:db";

// Type-safe queries
const posts = await db.select()
  .from(Post)
  .where(eq(Post.published, true))
  .orderBy(desc(Post.createdAt))
  .limit(10);

// Joins
const postsWithAuthors = await db.select({
  title: Post.title,
  authorName: Author.name,
})
  .from(Post)
  .innerJoin(Author, eq(Post.authorId, Author.columns.id));

// Aggregations
const stats = await db.select({
  authorId: Post.authorId,
  count: sql<number>`count(*)`,
})
  .from(Post)
  .groupBy(Post.authorId);
Enter fullscreen mode Exit fullscreen mode

4. Server Endpoints — API Routes with DB

// src/pages/api/posts.ts
import type { APIRoute } from "astro";
import { db, Post } from "astro:db";

export const GET: APIRoute = async () => {
  const posts = await db.select().from(Post).where(eq(Post.published, true));
  return new Response(JSON.stringify(posts));
};

export const POST: APIRoute = async ({ request }) => {
  const data = await request.json();
  const [post] = await db.insert(Post).values(data).returning();
  return new Response(JSON.stringify(post), { status: 201 });
};
Enter fullscreen mode Exit fullscreen mode

5. Studio — Visual Database Manager

astro db push     # Push schema to Astro Studio
astro db verify   # Verify remote schema matches local
astro db shell    # Interactive SQL shell
Enter fullscreen mode Exit fullscreen mode

Getting Started

npx astro add db
astro dev
Enter fullscreen mode Exit fullscreen mode

Need data from any website delivered as clean JSON? I build production web scrapers that handle anti-bot, proxies, and rate limits. 77 scrapers running in production. Email me: Spinov001@gmail.com

Check out my awesome-web-scraping list for the best scraping tools and resources.

Top comments (0)