How to Build a Backend API with Cloudflare Pages, D1 Database, Next.js, and Drizzle ORM

In modern development, creating high-performance backend API is more crucial. This guide will walk you through how to build a backend API with Cloudflare Pages and D1 Database, leveraging Next.js and Drizzle ORM to create high-performing backend service within minutes.

Build Backend API with Cloudflare Pages and D1 Database
Build Backend API with Cloudflare Pages and D1 Database

Why Use This Stack?

  • Cloudflare Pages pushes your application to edge servers worldwide, minimizing latency for end-users.
  • Serverless Architecture: With Cloudflare D1 and Cloudflare’s edge runtime, you eliminate the complexities of traditional server management.
  • Easy Database Manipulation: Drizzle ORM simplifies queries, schema definitions, and migrations in a type-safe manner.
  • Full-Stack Simplicity: Next.js enables you to keep frontend pages, API endpoints, and server-side rendering in a single codebase.

Prerequisites

Before you get started, make sure you have:

  • Cloudflare Account: Sign up for free if you haven’t already.
  • Node.js (v20.11.0 or later)
  • pnpm (v8.15.4 or later): Install pnpm if you haven’t:
npm install -g pnpm
  • Wrangler CLI: Cloudflare’s command-line tool for managing projects:
npm install -g wrangler
wrangler login

The wrangler login command will open a browser window to authenticate your Cloudflare account.

1. Clone the Template and Set Up Your Project

We’ll start by cloning a pre-configured template that incorporates Next.js, Drizzle ORM, and integration with Cloudflare’s D1 database.

  • Use the Template
    • Head to the nextjs-d1-drizzle-cloudflare-pages repository (replace # with the actual URL).
    • Click on Use this template to create your own repository.
  • Clone Your Repository
git clone <your-new-repo-url>
cd <your-new-repo-folder>
  • Install Dependencies
pnpm install
  • Set Up Environment Variables
    • Follow the template’s instructions to configure your .env file with necessary credentials for your D1 database and any other variables you need (e.g., API keys).

2. Deploy to Cloudflare Pages

With your code ready, connect the repository to Cloudflare Pages:

  1. Create a Cloudflare Pages Project
    • Log into the Cloudflare dashboard.
    • Create a new Pages project linked to your GitHub repository (or whichever version control system you use).
  2. Configure Build Settings
    • Build command: pnpm build
    • Output directory: the out or .next folder (depending on your configuration).
  3. Automatic Deployment
    • Whenever you push code to the linked repository, Cloudflare Pages will rebuild and redeploy your app automatically.

3. Implement a Sample “Add Product” Endpoint

Instead of creating a customer record, let’s create a new product in your D1 database.

1. Create Your Database Schema (using Drizzle): In your schema.ts file (or wherever you store Drizzle definitions), define the products table:

import { sqliteTable, text, integer, primaryKey } from "drizzle-orm/sqlite-core";

export const products = sqliteTable("products", {
  id: integer("id").primaryKey().autoIncrement(),
  name: text("name").notNull(),
  description: text("description").notNull(),
  price: integer("price").notNull(),
});

2. Set Up an API Route (in Next.js): Next.js allows you to create API routes under the pages/api directory or app/api directory if you’re using Next.js App Router. Here’s an example (pages/api/products/add.ts):

import { NextApiRequest, NextApiResponse } from "next";
import { db } from "@/lib/db";        // your Drizzle DB instance
import { products } from "@/lib/schema"; // table definition

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  if (req.method === "POST") {
    try {
      const { name, description, price } = req.body;

      // Validate input (simple example)
      if (!name || !description || !price) {
        return res.status(400).json({ error: "Missing required fields" });
      }

      // Insert into the database
      const result = await db.insert(products).values({
        name,
        description,
        price,
      });

      return res.status(200).json({ success: true, data: result });
    } catch (error) {
      console.error(error);
      return res.status(500).json({ error: "Failed to add product" });
    }
  } else {
    return res.status(405).json({ error: "Method not allowed" });
  }
}

3. Database Migrations: Drizzle provides a straightforward system to create and run migrations. Make sure to run your migrations so the products table is added to your D1 database:

pnpm drizzle:sync

(This command may vary depending on your template’s scripts.)

4. Test and Debug the API

4.1 Deploy (or Preview Locally)

  • Local Testing: You can run your Next.js app locally:
pnpm dev

Then test your endpoint via http://localhost:3000/api/products/add.

  • Cloudflare Preview: Use Wrangler to create a preview environment:
wrangler pages dev

This will run your application on a Cloudflare edge environment, letting you test the serverless deployment.

4.2 Use an API Debugging Tool

Tools like Postman or Apidog make it easy to send requests to your endpoint and verify responses:

  • Base URL: Set it to your deployment URL (e.g., https://your-app.pages.dev).
  • Endpoint: POST /api/products/add.
  • Body (JSON):
{
  "name": "Awesome T-Shirt",
  "description": "A stylish and comfortable t-shirt",
  "price": 1999
}
  • Send Request: Verify you get a 200 response and that the new product is inserted into your D1 database.

Conclusion

You’ve successfully built a highly responsive and globally distributed backend API using Cloudflare Pages, D1 Database, Next.js, and Drizzle ORM. By following this method:

  • Your API routes are easy to maintain and scale within Next.js.
  • D1 Database offers a serverless, globally distributed data layer with minimal overhead.
  • Drizzle ORM provides type-safe and friendly database interactions.
  • Cloudflare Pages ensures your application is delivered swiftly to users worldwide.

Dev Code Tips

  • Add More Tables: Expand your schema with categories, orders, or other relevant data structures.
  • Implement Authentication: Secure your endpoints using tokens, cookies, or session-based flows.
  • Optimize Performance: Take advantage of Cloudflare’s caching capabilities to reduce server hits.
  • Enhance Monitoring: Integrate logging or third-party monitoring tools to gain insights into traffic patterns and errors.

With this foundation, you have everything you need to develop and deploy modern, scalable applications quickly. Happy coding!

Leave a Comment

Comments

No comments yet. Why don’t you start the discussion?

    Comments