← Cloudflare Workers / workers / tutorials
Nasaďte aplikaci Express.js na Cloudflare Workers
V tomto tutoriálu se naučíte, jak nasadit Express.js ↗ aplikaci na Cloudflare Workers pomocí platforma Cloudflare Workers a databáze D1. Vytvoříte Members Registry API se základními operacemi Create, Read, Update a Delete (CRUD). Jako databázi pro ukládání a načítání dat o členech použijete D1.
Než začnete
Všechny návody předpokládají, že jste již dokončili Úvodní návod, který vás provede nastavením účtu Cloudflare Workers, C3 ↗, a Wrangler.
Rychlý start
Pokud chcete kroky přeskočit a rychle začít, vyberte Deploy to Cloudflare níže.
Tím se vytvoří repozitář ve vašem účtu GitHub a aplikace se nasadí na Cloudflare Workers. Tuto možnost použijte, pokud Cloudflare Workers dobře znáte a chcete přeskočit podrobné pokyny krok za krokem.
Pokud s Cloudflare Workers teprve začínáte, můžete kroky projít ručně.
1. Vytvořte nový projekt Cloudflare Workers
Použijte C3 ↗, nástroj příkazové řádky pro vývojářské produkty Cloudflare, k vytvoření nového adresáře a inicializaci nového projektu Worker:
npm create cloudflare@latest -- express-d1-appPři nastavení vyberte následující možnosti:
- Pro S čím byste chtěli začít?, vyberte
Hello World example. - Pro Jakou šablonu chcete použít?, vyberte
Worker only. - Pro Jaký jazyk chcete použít?, vyberte
TypeScript. - Pro Chcete používat git pro správu verzí?, vyberte
Yes. - Pro Chcete nasadit svou aplikaci?, vyberte
No(před nasazením provedeme ještě několik změn).
Přejděte do adresáře svého nového projektu:
cd express-d1-app2. Nainstalujte Express a závislosti
V tomto tutoriálu použijete Express.js ↗, oblíbený webový framework pro Node.js. Pokud chcete použít Express v prostředí Cloudflare Workers, nainstalujte Express spolu s potřebnými typy TypeScript:
npm i express @types/expressExpress.js na Cloudflare Workers vyžaduje nodejs_compat příznak kompatibility. Tento příznak zapíná Node.js API a umožňuje spuštění Express na Workers runtime. Do konfiguračního souboru Wrangler přidejte následující:
{
"compatibility_flags": [
"nodejs_compat"
]
}compatibility_flags = [ "nodejs_compat" ]3. Vytvořte databázi D1
Nyní vytvoříte databázi D1 pro ukládání informací o členech. Použijte wrangler d1 create příkaz pro vytvoření nové databáze:
npx wrangler d1 create members-dbPříkaz vytvoří novou databázi D1 a položí vám následující otázky:
- Chcete, aby to Wrangler přidal za vás?: Typ
Y. - Jaký název bindingu chcete použít?: Typ
DBa stiskněte Enter. - Chcete se pro lokální vývoj připojit ke vzdálenému prostředku místo k lokálnímu?: Typ
N.
⛅️ wrangler 4.44.0
───────────────────
✅ Successfully created DB 'members-db' in region WNAM
Created your new D1 database.
To access your new D1 Database in your Worker, add the following snippet to your configuration file:
{
"d1_databases": [
{
"binding": "members_db",
"database_name": "members-db",
"database_id": "<unique-ID-for-your-database>"
}
]
}
✔ Would you like Wrangler to add it on your behalf? … yes
✔ What binding name would you like to use? … DB
✔ For local dev, do you want to connect to the remote resource instead of a local resource? … noVazba (binding) bude přidána do vašeho konfiguračního souboru Wrangler.
{
"d1_databases": [
{
"binding": "DB",
"database_name": "members-db",
"database_id": "<unique-ID-for-your-database>"
}
]
}[[d1_databases]]
binding = "DB"
database_name = "members-db"
database_id = "<unique-ID-for-your-database>"4. Vytvořte schéma databáze
Vytvořte adresář s názvem schemas v kořenovém adresáři vašeho projektu a v něm vytvořte soubor s názvem schema.sql:
DROP TABLE IF EXISTS members;
CREATE TABLE IF NOT EXISTS members (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT NOT NULL UNIQUE,
joined_date TEXT NOT NULL
);
-- Insert sample data
INSERT INTO members (name, email, joined_date) VALUES
('Alice Johnson', '[email protected]', '2024-01-15'),
('Bob Smith', '[email protected]', '2024-02-20'),
('Carol Williams', '[email protected]', '2024-03-10');Toto schéma vytvoří members tabulku s automaticky se zvyšujícím ID a poli pro jméno, e-mail a datum vstupu. Zároveň vloží tři ukázkové členy.
Spusťte soubor se schématem proti vaší databázi D1:
npx wrangler d1 execute members-db --file=./schemas/schema.sqlVýše uvedený příkaz vytvoří tabulku ve vaší lokální vývojové databázi. Schéma nasadíte do produkce později.
5. Inicializujte aplikaci Express
Aktualizujte src/index.ts soubor pro nastavení Express s TypeScriptem. Obsah souboru nahraďte následujícím:
import { env } from "cloudflare:workers";
import { httpServerHandler } from "cloudflare:node";
import express from "express";
const app = express();
// Middleware to parse JSON bodies
app.use(express.json());
// Health check endpoint
app.get("/", (req, res) => {
res.json({ message: "Express.js running on Cloudflare Workers!" });
});
app.listen(3000);
export default httpServerHandler({ port: 3000 });Tento kód inicializuje Express a vytváří základní endpoint pro kontrolu stavu. Klíčovým importem je import { env } from "cloudflare:workers" umožňuje přístup k vazby jako je vaše databáze D1, odkudkoli z vašeho kódu. httpServerHandler integruje Express s Workers runtime a umožňuje vaší aplikaci zpracovávat HTTP požadavky v síti Cloudflare.
Dále spusťte příkaz typegen, který vygeneruje definice typů pro prostředí vašeho Workeru:
npm run cf-typegen6. Implementujte operace čtení
Přidejte koncové body pro načítání členů z databáze. Upravte svůj src/index.ts soubor přidáním následujících tras za endpoint pro kontrolu stavu (health check):
// GET all members
app.get('/api/members', async (req, res) => {
try {
const { results } = await env.DB.prepare('SELECT * FROM members ORDER BY joined_date DESC').all();
res.json({ success: true, members: results });
} catch (error) {
res.status(500).json({ success: false, error: 'Failed to fetch members' });
}
});
// GET a single member by ID
app.get('/api/members/:id', async (req, res) => {
try {
const { id } = req.params;
const { results } = await env.DB.prepare('SELECT * FROM members WHERE id = ?').bind(id).all();
if (results.length === 0) {
return res.status(404).json({ success: false, error: 'Member not found' });
}
res.json({ success: true, member: results[0] });
} catch (error) {
res.status(500).json({ success: false, error: 'Failed to fetch member' });
}
});Tyto trasy používají D1 binding (env.DB) k přípravě příkazů SQL a jejich spuštění. Protože jste importovali env z cloudflare:workers v horní části souboru je dostupná v celé vaší aplikaci. prepare, bind, a all metody na D1 bindingu umožňují bezpečně dotazovat databázi. Více informací najdete v D1 Workers Binding API pro všechny dostupné metody.
7. Implementujte operaci vytvoření
Přidejte koncový bod pro vytváření nových členů. Přidejte následující trasu do svého src/index.ts soubor:
// POST - Create a new member
app.post("/api/members", async (req, res) => {
try {
const { name, email } = req.body;
// Validate input
if (!name || !email) {
return res.status(400).json({
success: false,
error: "Name and email are required",
});
}
// Basic email validation (simplified for tutorial purposes)
// For production, consider using a validation library or more comprehensive checks
if (!email.includes("@") || !email.includes(".")) {
return res.status(400).json({
success: false,
error: "Invalid email format",
});
}
const joined_date = new Date().toISOString().split("T")[0];
const result = await env.DB.prepare(
"INSERT INTO members (name, email, joined_date) VALUES (?, ?, ?)"
)
.bind(name, email, joined_date)
.run();
if (result.success) {
res.status(201).json({
success: true,
message: "Member created successfully",
id: result.meta.last_row_id,
});
} else {
res
.status(500)
.json({ success: false, error: "Failed to create member" });
}
} catch (error: any) {
// Handle unique constraint violation
if (error.message?.includes("UNIQUE constraint failed")) {
return res.status(409).json({
success: false,
error: "Email already exists",
});
}
res.status(500).json({ success: false, error: "Failed to create member" });
}
});Tento endpoint validuje vstup, kontroluje formát e-mailu a vkládá nového člena do databáze. Zároveň řeší duplicitní e-mailové adresy kontrolou porušení omezení jedinečnosti.
8. Implementujte operaci aktualizace
Přidejte koncový bod pro aktualizaci stávajících členů. Přidejte následující trasu do svého src/index.ts soubor:
app.put("/api/members/:id", async (req, res) => {
try {
const { id } = req.params;
const { name, email } = req.body;
// Validate input
if (!name && !email) {
return res.status(400).json({
success: false,
error: "At least one field (name or email) is required",
});
}
// Basic email validation if provided (simplified for tutorial purposes)
// For production, consider using a validation library or more comprehensive checks
if (email && (!email.includes("@") || !email.includes("."))) {
return res.status(400).json({
success: false,
error: "Invalid email format",
});
}
// Build dynamic update query
const updates: string[] = [];
const values: any[] = [];
if (name) {
updates.push("name = ?");
values.push(name);
}
if (email) {
updates.push("email = ?");
values.push(email);
}
values.push(id);
const result = await env.DB.prepare(
`UPDATE members SET ${updates.join(", ")} WHERE id = ?`
)
.bind(...values)
.run();
if (result.meta.changes === 0) {
return res
.status(404)
.json({ success: false, error: "Member not found" });
}
res.json({ success: true, message: "Member updated successfully" });
} catch (error: any) {
if (error.message?.includes("UNIQUE constraint failed")) {
return res.status(409).json({
success: false,
error: "Email already exists",
});
}
res.status(500).json({ success: false, error: "Failed to update member" });
}
});Tento endpoint umožňuje aktualizovat jméno, e-mail nebo obě pole u existujícího člena. Sestavuje dynamický dotaz SQL na základě zadaných polí.
9. Implementujte operaci odstranění
Přidejte koncový bod pro odstraňování členů. Přidejte následující trasu do svého src/index.ts soubor:
// DELETE - Delete a member
app.delete("/api/members/:id", async (req, res) => {
try {
const { id } = req.params;
const result = await env.DB.prepare("DELETE FROM members WHERE id = ?")
.bind(id)
.run();
if (result.meta.changes === 0) {
return res
.status(404)
.json({ success: false, error: "Member not found" });
}
res.json({ success: true, message: "Member deleted successfully" });
} catch (error) {
res.status(500).json({ success: false, error: "Failed to delete member" });
}
});Tento endpoint odstraní člena podle jeho ID a vrátí chybu, pokud daný člen neexistuje.
10. Otestujte lokálně
Spusťte vývojový server pro místní testování API:
npm run devSpustí se vývojový server a vaše API bude dostupné na adrese http://localhost:8787.
Otevřete nové okno terminálu a otestujte endpointy pomocí curl:
curl http://localhost:8787/api/members{
"success": true,
"members": [
{
"id": 1,
"name": "Alice Johnson",
"email": "[email protected]",
"joined_date": "2024-01-15"
},
{
"id": 2,
"name": "Bob Smith",
"email": "[email protected]",
"joined_date": "2024-02-20"
},
{
"id": 3,
"name": "Carol Williams",
"email": "[email protected]",
"joined_date": "2024-03-10"
}
]
}Otestujte vytvoření nového člena:
curl -X POST http://localhost:8787/api/members \
-H "Content-Type: application/json" \
-d '{"name": "David Brown", "email": "[email protected]"}'{
"success": true,
"message": "Member created successfully",
"id": 4
}Otestujte získání jednoho člena:
curl http://localhost:8787/api/members/1Otestujte aktualizaci člena:
curl -X PUT http://localhost:8787/api/members/1 \
-H "Content-Type: application/json" \
-d '{"name": "Alice Cooper"}'Otestujte odstranění člena:
curl -X DELETE http://localhost:8787/api/members/411. Nasaďte do Cloudflare Workers
Než nasadíte do produkce, spusťte soubor se schématem databáze proti vaší vzdálené (produkční) databázi:
npx wrangler d1 execute members-db --remote --file=./schemas/schema.sqlNyní nasaďte svou aplikaci do sítě Cloudflare:
npm run deploy⛅️ wrangler 4.44.0
───────────────────
Total Upload: 1743.64 KiB / gzip: 498.65 KiB
Worker Startup Time: 48 ms
Your Worker has access to the following bindings:
Binding Resource
env.DB (members-db) D1 Database
Uploaded express-d1-app (2.99 sec)
Deployed express-d1-app triggers (5.26 sec)
https://<your-subdomain>.workers.dev
Current Version ID: <version-id>Po úspěšném nasazení Wrangler vypíše adresu URL vašeho Workeru.
12. Otestujte nasazení do produkce
Otestujte nasazené API pomocí poskytnuté adresy URL. Nahraďte <your-worker-url> skutečnou URL adresou vašeho Workeru:
curl https://<your-worker-url>/api/membersMěli byste vidět stejná data členů, jaká jste vytvořili v produkční databázi.
Vytvořte nového člena v produkčním prostředí:
curl -X POST https://<your-worker-url>/api/members \
-H "Content-Type: application/json" \
-d '{"name": "Eva Martinez", "email": "[email protected]"}'Vaše aplikace Express.js s databází D1 nyní běží na Cloudflare Workers.
Závěr
V tomto tutoriálu jste sestavili Members Registry API pomocí Express.js a databáze D1 a poté jste jej nasadili na Cloudflare Workers. Implementovali jste kompletní operace CRUD (Create, Read, Update, Delete) a naučili jste se, jak:
- Nastavit aplikaci Express.js pro Cloudflare Workers
- Vytvoření a konfigurace databáze D1 s bindings
- Implementujte databázové operace pomocí prepared statements D1
- Otestujte své API lokálně i v produkci
Další kroky
- Další informace o Funkce databáze D1
- Prozkoumejte Směrování a middleware Workers
- Přidejte do svého API autentizaci pomocí Ověřování ve Workers
- Implementujte stránkování velkých datových sad pomocí Optimalizace dotazů D1