מדריך קלאודפלייר בעברית

תיעוד 203

חיבור למסד נתונים של MongoDB עם Cloudflare Workers

במדריך זה תלמדו איך ליצור יישום Cloudflare Workers ולחבר אותו למסד נתונים של MongoDB באמצעות מנהל ההתקן המקורי של Node.js. תתחילו בחיבור ישיר מתוך Worker, ואחר כך תשתמשו ב-Durable Object כדי לשמור חיבורים ולהפחית את זמן ההמתנה.

הערה

Hyperdrive לא תומך ב-MongoDB. Hyperdrive תומך רק בפרוטוקולי התקשורת של PostgreSQL ושל MySQL. כדי להפחית את זמן ההמתנה של החיבור עם MongoDB, השתמשו ב-Durable Object כמו שמוצג במדריך זה.

#דרישות מקדימות

כדי להמשיך:

  1. הירשמו ל-חשבון Cloudflare ↗︎ אם עדיין אין לכם חשבון.
  2. התקינו את npm ↗︎.
  3. התקינו את Node.js ↗︎. השתמשו במנהל גרסאות של Node כמו Volta ↗︎ או nvm ↗︎ כדי להימנע מבעיות הרשאות וכדי להחליף גרסאות של Node.js.
  4. ודאו שיש לכם גישה למסד נתונים של MongoDB. אפשר להשתמש ב-MongoDB Atlas ↗︎, במופע MongoDB בהתקנה עצמית, או בכל מארח אחר שתואם ל-MongoDB.

#1. יצירת יישום Worker

קודם, השתמשו ב-create-cloudflare CLI ↗︎ כדי ליצור יישום Worker חדש. כדי לעשות זאת, פתחו חלון מסוף והריצו את הפקודה הבאה:

npm:

npm create cloudflare@latest -- mongodb-tutorial

yarn:

yarn create cloudflare mongodb-tutorial

pnpm:

pnpm create cloudflare@latest mongodb-tutorial

הפקודה תבקש מכם להתקין את החבילה create-cloudflare ↗︎ ותוביל אתכם באשף ההגדרה.

להגדרה, בחרו את האפשרויות הבאות:

  • עבור What would you like to start with?, בחרו Hello World example.
  • עבור Which template would you like to use?, בחרו Worker only.
  • עבור Which language do you want to use?, בחרו TypeScript.
  • עבור Do you want to use git for version control?, בחרו Yes.
  • עבור Do you want to add an AGENTS.md file to help AI coding tools understand Cloudflare APIs?, בחרו Yes.
  • עבור Do you want to deploy your application?, בחרו No (נבצע כמה שינויים לפני הפריסה).

אם תבחרו לפרוס, תתבקשו לאמת את הזהות (אם עדיין לא התחברתם), והפרויקט ייפרס. אם תפרסו, עדיין תוכלו לשנות את קוד ה-Worker ולפרוס שוב בסוף המדריך.

עכשיו, עברו לתיקייה שנוצרה:

cd mongodb-tutorial

#2. הפעלת תאימות ל-Node.js

תאימות ל-Node.js נדרשת למנהל ההתקן של MongoDB, וצריך להגדיר אותה לפרויקט ה-Workers שלכם.

עבור תאריכי תאימות של 2026-08-04 או מאוחר יותר, פרויקטים של Workers ושל Pages מפעילים כברירת מחדל גם את nodejs_compat וגם את nodejs_compat_v2. ממשקי API מובנים של סביבת הריצה ו-polyfills זמינים בלי הגדרה נוספת. הדגלים האלה לא בשימוש עבור תאריכי התאימות האלה. פרויקטים קיימים לא צריכים להסיר אותם כשמעדכנים את תאריך התאימות.

אם תאריך התאימות שלכם מוקדם מ-2026-08-04, הוסיפו את דגל התאימות nodejs_compat לקובץ ההגדרות של Wrangler כדי להצטרף:

{
	"compatibility_flags": [
		"nodejs_compat"
	]
}
compatibility_flags = [ "nodejs_compat" ]

כדי לכבות לגמרי את תאימות Node.js עבור תאריך תאימות של 2026-08-04 או מאוחר יותר, הסירו את הדגלים החיוביים אם הם קיימים. אחר כך הוסיפו גם את no_nodejs_compat וגם את no_nodejs_compat_v2. לדוגמאות הגדרה, ראו את דגל התאימות של Node.js.

#3. הוספת ספריית החיבור ל-MongoDB

כדי להתחבר למסד נתונים של MongoDB, תצטרכו את הספרייה mongodb. בתיקיית יישום ה-Worker, הריצו את הפקודה הבאה כדי להתקין את הספרייה:

npm:

npm i mongodb

yarn:

yarn add mongodb

pnpm:

pnpm add mongodb

bun:

bun add mongodb

הערה

ודאו שאתם משתמשים בגרסה 6.15.0 של mongodb או גבוהה יותר.

#4. הגדרת החיבור למסד הנתונים של MongoDB

הגדירו את מחרוזת החיבור של MongoDB כסוד כדי שהיא לא תישמר כטקסט גלוי. השתמשו ב-wrangler secret put עם שם המשתנה לדוגמה MONGODB_URI:

npx wrangler secret put MONGODB_URI

הגדירו את הסוד MONGODB_URI באופן מקומי בקובץ .env, כפי שמתועד ב-Local Development with Secrets:

.env

MONGODB_URI="<ENTER YOUR MONGODB CONNECTION STRING>"

#5. חיבור למסד הנתונים של MongoDB בתוך ה-Worker

פתחו את הקובץ הראשי של ה-Worker (לדוגמה, src/index.ts) וייבאו את המחלקה MongoClient מהספרייה mongodb:

import { MongoClient } from "mongodb";

במטפל האירוע fetch, צרו מופע חדש של MongoClient והתחברו למסד הנתונים של MongoDB.

// create a new MongoClient instance using the connection string
const client = new MongoClient(env.MONGODB_URI);
// connect to the MongoDB database
await client.connect();

#6. אינטראקציה עם מסד הנתונים של הסרטים

כדי להדגים איך לקיים אינטראקציה עם מסד הנתונים של הסרטים, תביאו מסמך מהאוסף movies על ידי שאילתה על האוסף כשמתקבלת בקשה.

הערה

אם אתם עוקבים עם MongoDB Atlas, אפשר להשתמש במערך הנתונים לדוגמה sample_mflix. כדי לטעון את הנתונים האלה, פתחו את קונסולת Atlas, נווטו לאשכול שלכם, ובחרו Load Sample Dataset.

החליפו את הקוד הקיים בקובץ src/index.ts בקוד הבא:

src/index.js

import { MongoClient } from "mongodb";

export default {
	async fetch(request, env, ctx) {
		const client = new MongoClient(env.MONGODB_URI);
		await client.connect();

		const movie = await client
			.db("sample_mflix")
			.collection("movies")
			.findOne(
				{ title: "The Room" },
				{ projection: { _id: 0, title: 1, imdb: 1 } },
			);

		return Response.json({ movie });
	},
};

src/index.ts

import { MongoClient } from "mongodb";

export interface Env {
	MONGODB_URI: string;
}

export default {
	async fetch(request, env, ctx): Promise<Response> {
		const client = new MongoClient(env.MONGODB_URI);
		await client.connect();

		const movie = await client
			.db("sample_mflix")
			.collection("movies")
			.findOne(
				{ title: "The Room" },
				{ projection: { _id: 0, title: 1, imdb: 1 } },
			);

		return Response.json({ movie });
	},
} satisfies ExportedHandler<Env>;

הקוד הזה מקים חיבור למסד הנתונים של MongoDB בתוך יישום ה-Worker ושולח שאילתה לאוסף movies, ומחזיר את התוצאה כתשובת JSON.

#7. פריסת ה-Worker

הריצו את הפקודה הבאה כדי לפרוס את ה-Worker:

npx wrangler deploy

אחרי הפריסה, אפשר לקיים אינטראקציה עם מסד הנתונים של MongoDB באמצעות ה-Cloudflare Worker שלכם. בכל פעם שנשלחת בקשה לכתובת ה-URL של ה-Worker, הוא יביא נתונים מהאוסף movies ויחזיר אותם כתשובת JSON.

#8. שימוש ב-Durable Object כדי להאיץ שאילתות

כל הפעלה של Worker יוצרת חיבור TCP ו-TLS חדש אל MongoDB. לשימושים עם תעבורה נמוכה, זה מקובל. ליישומים שרגישים לזמן המתנה, מקמו את MongoClient בתוך Durable Object כדי לשמור את החיבור בין בקשות.

צרו קובץ חדש למחלקת ה-Durable Object:

src/MongoDBConnection.js

import { DurableObject } from "cloudflare:workers";
import { MongoClient } from "mongodb";

export class MongoDBConnection extends DurableObject {
	client;

	constructor(state, env) {
		super(state, env);
		this.client = new MongoClient(env.MONGODB_URI, {
			maxPoolSize: 1,
			minPoolSize: 0,
			serverSelectionTimeoutMS: 5000,
			maxIdleTimeMS: 20_000,
		});
	}

	async getMovie() {
		await this.client.connect();
		return this.client
			.db("sample_mflix")
			.collection("movies")
			.findOne(
				{ title: "The Room" },
				{ projection: { _id: 0, title: 1, imdb: 1 } },
			);
	}
}

src/MongoDBConnection.ts

import { DurableObject } from "cloudflare:workers";
import { MongoClient } from "mongodb";

interface Env {
	MONGODB_URI: string;
}

export class MongoDBConnection extends DurableObject<Env> {
	private client: MongoClient;

	constructor(state: DurableObjectState, env: Env) {
		super(state, env);
		this.client = new MongoClient(env.MONGODB_URI, {
			maxPoolSize: 1,
			minPoolSize: 0,
			serverSelectionTimeoutMS: 5000,
			maxIdleTimeMS: 20_000,
		});
	}

	async getMovie() {
		await this.client.connect();
		return this.client
			.db("sample_mflix")
			.collection("movies")
			.findOne(
				{ title: "The Room" },
				{ projection: { _id: 0, title: 1, imdb: 1 } },
			);
	}
}

עדכנו את נקודת הכניסה של ה-Worker כדי לנתב בקשות אל ה-Durable Object:

src/index.js

import { MongoDBConnection } from "./MongoDBConnection";

export default {
	async fetch(request, env) {
		const id = env.MONGODB_CONNECTION.idFromName("mongodb-connection");
		const stub = env.MONGODB_CONNECTION.get(id, { locationHint: "enam" });
		const movie = await stub.getMovie();
		return Response.json({ movie });
	},
};

export { MongoDBConnection };

src/index.ts

import { MongoDBConnection } from "./MongoDBConnection";

interface Env {
	MONGODB_URI: string;
	MONGODB_CONNECTION: DurableObjectNamespace<MongoDBConnection>;
}

export default {
	async fetch(request: Request, env: Env): Promise<Response> {
		const id = env.MONGODB_CONNECTION.idFromName("mongodb-connection");
		const stub = env.MONGODB_CONNECTION.get(id, { locationHint: "enam" });
		const movie = await stub.getMovie();
		return Response.json({ movie });
	},
} satisfies ExportedHandler<Env>;

export { MongoDBConnection };

השתמשו באפשרות locationHint כדי למקם את ה-Durable Object קרוב לאשכול MongoDB שלכם.

הגדירו את ה-binding של ה-Durable Object ואת ה-migration בקובץ Wrangler:

{
  "$schema": "./node_modules/wrangler/config-schema.json",
  "name": "mongodb-tutorial",
  "main": "src/index.ts",
  // Set this to today's date
  "compatibility_date": "2026-10-17",
  "compatibility_flags": [
    "nodejs_compat"
  ],
  "durable_objects": {
    "bindings": [
      {
        "name": "MONGODB_CONNECTION",
        "class_name": "MongoDBConnection"
      }
    ]
  },
  "migrations": [
    {
      "tag": "v1",
      "new_classes": [
        "MongoDBConnection"
      ]
    }
  ]
}
name = "mongodb-tutorial"
main = "src/index.ts"
# Set this to today's date
compatibility_date = "2026-10-17"
compatibility_flags = ["nodejs_compat"]

[[durable_objects.bindings]]
name = "MONGODB_CONNECTION"
class_name = "MongoDBConnection"

[[migrations]]
tag = "v1"
new_classes = ["MongoDBConnection"]

#9. פריסה מחדש של ה-Worker

הריצו את הפקודה הבאה כדי לפרוס את ה-Worker:

npx wrangler deploy

יישום ה-Worker שלכם פעיל עכשיו ונגיש בכתובת <YOUR_WORKER>.<YOUR_SUBDOMAIN>.workers.dev, ומשתמש ב-Durable Object כדי לשמור חיבורי MongoDB. זה מפחית את זמן ההמתנה של השאילתה מכ-300 ms בבקשות קרות לכ-35 ms בבקשות חמות.

#שיקולים לגבי Durable Object

  • החיבור נעשה בשימוש חוזר רק כל עוד ה-Durable Object נשאר בזיכרון. אחרי דקה או שתיים בלי בקשות, ה-Durable Object מפונה והחיבור שלו נסגר. הבקשה הבאה מקימה את החיבור מחדש ומשלמת שוב את עלות ההתחלה הקרה. זו התנהגות צפויה. אין shutdown hook כדי לסגור את החיבור ידנית, ואין צורך באחד כזה.
  • הריצו את כל לוגיקת מסד הנתונים בתוך ה-Durable Object. אי אפשר להחזיר אובייקטים מסוג MongoClient, Db או Collection אל ה-Worker הקורא דרך RPC.
  • מופע יחיד של Durable Object מטפל בערך ב-1,000 בקשות בשנייה. כדי להתרחב מעבר לזה, פזרו בקשות בין כמה מופעים.

#השלבים הבאים

כדי לבנות עוד עם מסדי נתונים ו-Workers, ראו את Tutorials ועיינו בתיעוד Databases.

אם יש לכם שאלות, אתם צריכים עזרה, או שתרצו לשתף את הפרויקט, הצטרפו לקהילת המפתחים של Cloudflare ב-Discord ↗︎ כדי להתחבר למפתחים אחרים ולצוות Cloudflare.