🗒️使用 Cloudflare Pages 建立 Serverless Next.js API (with D1 database)[转]

Post on:2024-8-15|Last edited: 2024-8-15|
type
status
date
slug
summary
tags
category
icon
password
URL
Link
Publish Time
Podcast
前言 留言 Cloudflare pages 可以根據 github commit 建立每個 Pull Request 的 staging 網頁
有這樣的 staging deployment 可以有利於 PR review 及 debug。
我們也可以用 Cloudflare 提供的 pages/workers 建立 serverless framework 處理 API,省去架設伺服器的困難及成本。
並用 D1 database 儲存資料,避免 serverless 狀態被清除。
文件 pages: https://developers.cloudflare.com/pages d1: https://developers.cloudflare.com/d1 部署 Next.js site 參考 Pages: Deploy a Next.js site
Create 一個 next.js project
npm create cloudflare@latest nextjs-pages-example -- --framework=next 設定 config 接著進入資料夾
cd nextjs-pages-example 原本應該就有個 default 的 api/hello
上傳到 Github
git remote add origin https://github.com/<GITHUB_USER_NAME>/nextjs-pages-example.git git branch -M main git push -u origin main 到 Cloudflare Workers 和 Pages 建立應用程式
選擇 Pages 的 tab,並選連線至 Git
選擇 project 的 repository 並按 開始設定 選擇 Next.js 的設定
進到 設定 中的 函數
選擇相容性日期: 2022-11-30 (生產跟預覽)
設定相容性旗標: nodejs_compat (生產跟預覽)
再部署一次
可以在新的 url 下呼叫 api/hello e.g. https://c030509d.nextjs-pages-example.pages.dev/api/hello
建立 D1 database 參考 D1: Get Started
登入 Cloudflare npx wrangler login 新增 database 名稱為 prod-d1-tutorial npx wrangler d1 create prod-d1-tutorial 如果成功會出現 d1 資訊 [[d1_databases]] binding = "DB" # available in your Worker on env.DB database_name = "prod-d1-tutorial" database_id = "<unique-ID-for-your-database>" 在 root 建立一個 wrangler.toml 檔案 [[d1_databases]] binding = "DB" # available in your Worker on env.DB database_name = "prod-d1-tutorial" database_id = "<unique-ID-for-your-database>" 在 root 建立一個 schema.sql 檔案 DROP TABLE IF EXISTS Customers; CREATE TABLE IF NOT EXISTS Customers (CustomerId INTEGER PRIMARY KEY, CompanyName TEXT, ContactName TEXT); INSERT INTO Customers (CustomerID, CompanyName, ContactName) VALUES (1, 'Alfreds Futterkiste', 'Maria Anders'), (4, 'Around the Horn', 'Thomas Hardy'), (11, 'Bs Beverages', 'Victoria Ashworth'), (13, 'Bs Beverages', 'Random Name'); 執行此 sql 指令 npx wrangler d1 execute prod-d1-tutorial --local --file=./schema.sql 若帶上 --local 的 flag 則表示只在 local 執行,不會變更到 Cloudflare D1 裡的資料 並會在 root 資料夾新增一個 .wrangler 資料夾 儲存 D1 的資料 檢查是否儲存成功 npx wrangler d1 execute prod-d1-tutorial --local --command="SELECT * FROM Customers" 會回傳 🌀 Mapping SQL input into an array of statements 🌀 Executing on local database prod-d1-tutorial (21c8234f-e616-4128-93bc-b65ff78b73f5) from .wrangler/state/v3/d1: ┌────────────┬─────────────────────┬───────────────────┐ │ CustomerId │ CompanyName │ ContactName │ ├────────────┼─────────────────────┼───────────────────┤ │ 1 │ Alfreds Futterkiste │ Maria Anders │ ├────────────┼─────────────────────┼───────────────────┤ │ 4 │ Around the Horn │ Thomas Hardy │ ├────────────┼─────────────────────┼───────────────────┤ │ 11 │ Bs Beverages │ Victoria Ashworth │ ├────────────┼─────────────────────┼───────────────────┤ │ 13 │ Bs Beverages │ Random Name │ └────────────┴─────────────────────┴───────────────────┘
若要上傳此 data 到 D1 則把 --local flag 去掉 建立呼叫 D1 的 API 在 root 建立一個 env.d.ts 的檔案 參考 Pages: Use bindings in your Next.js application
declare global { namespace NodeJS { interface ProcessEnv { [key: string]: string | undefined; DB: D1Database; } } }
export { }; 建立一個 src/app/api/db/route.ts 的檔案 回傳 DB 中的資料 import type { NextRequest } from 'next/server'
export const runtime = 'edge'
export async function GET(request: NextRequest) { const { results } = await process.env.DB.prepare( "SELECT * FROM Customers WHERE CompanyName = ?" ) .bind("Bs Beverages") .all(); return new Response(JSON.stringify(results)); } 設定 D1 資料庫繫結 DB = prod-d1-tutorial(生產和預覽)
此時 push code 到 github,就能看到新 deploy 的 pages 有 api/db 回傳 D1 的資料。 e.g. https://c97ea8ef.nextjs-pages-example.pages.dev/api/db 如何在 local 測試 D1 pages 參考 Pages: Interact with your D1 databases locally
用在 cloudflare 的設定 build:
npx @cloudflare/next-on-pages@1 ⚠️ 每次更動 router 都必須執行此指定一次。 也必須重開 server
用 npx wrangler pages dev 啟動 server,並設定以下 flags
npx wrangler pages dev .vercel/output/static \ --compatibility-date 2022-11-30 \ --compatibility-flag nodejs_compat \ --d1 DB=<unique-ID-for-your-database> e.g. 我的 id = 21c8234f-e616-4128-93bc-b65ff78b73f5
npx wrangler pages dev .vercel/output/static \ --compatibility-date 2022-11-30 \ --compatibility-flag nodejs_compat \ --d1 DB=21c8234f-e616-4128-93bc-b65ff78b73f5 雖然不是真的跟 Cloudflare的 D1 互動,但是還是要用 cloudflare 上的 db id
Vite SSR 项目 Docker 镜像最小化打包方案我把网站迁移到 cf,省了几万块[转]
Loading...