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.
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.
- Head to the nextjs-d1-drizzle-cloudflare-pages repository (replace
- 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).
- Follow the template’s instructions to configure your
2. Deploy to Cloudflare Pages
With your code ready, connect the repository to Cloudflare Pages:
- 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).
- Configure Build Settings
- Build command:
pnpm build
- Output directory: the
out
or.next
folder (depending on your configuration).
- Build command:
- 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!