הבנת דפוס Backend for Frontend (BFF): מדריך פשוט

הבנת דפוס Backend for Frontend (BFF): מדריך פשוט

בארכיטקטורת מיקרו-שירותים, המערכות שלנו מחולקות לעשרות שירותים קטנים וממוקדים - כמו שירות משתמש, שירות הזמנות ושירות מוצר.

אבל כשזה מגיע להצגת המידע הזה למשתמשים שלך, למכשירים שונים יש צרכים שונים מאוד. דפדפן אינטרנט במחשב שולחני מהיר רוצה לוח מחוונים עשיר מלא בטבלאות, סרגלי צד וגרפים. אפליקציה לנייד ברשת סלולרית איטית רוצה פריסה פשוטה וקלה כדי לחסוך ברוחב פס ובסוללה. אפליקציית שעון חכם עשויה להזדקק רק לשורה אחת של טקסט.

אם כל החזיתות הללו מבצעות שאילתות בדיוק על אותו ממשק API, מישהו צריך להתפשר. או שהאפליקציה לנייד נאלצת להוריד כמויות אדירות של נתונים חסרי תועלת, או שאפליקציית האינטרנט נאלצת לבצע עשרות בקשות רשת נפרדות כדי להביא את כל מה שהיא צריכה.

זו הבעיה המדויקת שנפתרה על ידי דפוס Backend for Frontend (BFF). במדריך זה, נסביר את הדפוס הזה במילים פשוטות, נסתכל על אנלוגיה של העולם האמיתי, נשווה אותה לשער API סטנדרטי, ונעבור על יישום קוד מעשי.


האנלוגיה של העולם האמיתי: תפריט המסעדה

תארו לעצמכם מסעדה המשרתת שלושה סוגים שונים מאוד של סועדים:

  1. מבקר אוכל שרוצה תפריט טעימות מלא בן 5 מנות עם רשימות מרכיבים מפורטות.
  2. נוסע עסוק שרוצה חטיף מהיר וארוז מראש לאכול ברכבת.
  3. ילד שרוצה ארוחת ילדים פשוטה עם מנות קטנות וללא מרכיבים חריפים.

אם למסעדה היה רק ​​תפריט בודד שמפרט את כל שלוש האפשרויות בפירוט מלא, זה היה מהמם. הנוסע היה מבזבז זמן בקריאת מתכונים של 5 מנות, והוריו של הילד היו נאבקים למצוא אפשרויות אוכל פשוטות.

במקום זאת, המסעדה מדפיסה שלושה תפריטים מותאמים אישית: תפריט טעימות, תפריט אקספרס לדרך ותפריט ילדים.

כל תפריט שואב מאותו מטבח (המיקרו-שירותים), אבל מעצב ומתאים את האפשרויות באופן ספציפי לאותו לקוח (הלקוח).

בתרחיש זה:

  • המטבח מייצג את שירותי המיקרו שלך (משתמש, קטלוג, תשלום).
  • התפריטים המותאמים אישית הם הBFFs שלך (Web BFF, Mobile BFF, Watch BFF).
  • הסועדים הם החזיתות שלכם (דפדפן שולחני, אפליקציה לנייד, שעון חכם).

הבעיה: ה-API “One-Size-Fits-All”.

כאשר שירותי מיקרו הפכו פופולריים לראשונה, צוותים רבים בנו שער API משותף יחיד כדי לטפל בכל לקוחות החזית:

תרשים ארכיטקטורת Backend for Frontend (BFF) המשווה בין זרימות אינטרנט ומובייל

בעוד שנקודת כניסה יחידה היא נהדרת, ממשק API משותף מציג מספר צווארי בקבוק להרחבה:

  • Payload Bloat לנייד: אפליקציית האינטרנט של שולחן העבודה זקוקה להיסטוריית ההזמנות, כתובת החיוב, תמונת הפרופיל ונקודות הנאמנות של המשתמש. האפליקציה לנייד צריכה להראות רק “הזמנה אחרונה: נשלחה”. עם API משותף, האפליקציה לנייד מורידה את כל מטען הפרופיל, מבזבזת נתונים יקרים ומאטה את זמני הטעינה.
  • צווארי בקבוק של API: צוות יחיד הופך לצוואר הבקבוק עבור השער המשותף. אם צוות iOS רוצה לשנות שדה פריסה קטן, עליהם לחכות שצוות השער המשותף יפרוס גרסה חדשה, מה שיאט את מחזורי הפיתוח.
  • צורכי אבטחה שונים: דפדפן אינטרנט עשוי לדרוש הפעלות מבוססות קובצי Cookie כדי למנוע Scripting חוצה אתרים (XSS), בעוד שאפליקציה לנייד מעדיפה כותרות OAuth מבוססות אסימונים. טיפול בשניהם בשרת יחיד יוצר קוד מורכב ומבולגן.

הפתרון: תבנית ה-BFF

במקום ליצור שער ענק אחד לכל המכשירים, BFF Pattern דוגל בבניית שרת אחורי ייעודי אחד לכל יישום חזיתי.

יהיו לך:

  • ** Web BFF**: מטפל בבקשות מדפדפן שולחן העבודה. הוא אוסף פרופילים מלאים, קטלוגים של מוצרים ומידע מפורט על תשלום.
  • BFF לנייד: מטפל בבקשות מאפליקציות iOS ו-Android. הוא צובר נתונים, מסנן שדות מיותרים ודוחס את התגובה הסופית כדי להבטיח ביצועים מהירים.

שער API לעומת BFF: מה ההבדל?

מקובל לבלבל בין שני הדפוסים הללו מכיוון ששניהם יושבים בין הלקוח לשירותי המיקרו. הנה ההבחנה:

תכונה שער API כללי Backend for Frontend (BFF)
מספר שערים בדרך כלל אחד לכל המערכת. מרובה (אחד לכל סוג של מכשיר לקוח).
אחריות ניתוב ברמה גבוהה, הגבלת תעריפים ואבטחה גלובלית. צבירת נתונים והתאמת מטענים עבור חזית ספציפית.
בעלות מנוהל על ידי צוות backend/פלטפורמת תשתית ייעודי. מנוהל על ידי צוות החזית הבונה את האפליקציה המתאימה.
התאמה אישית נָמוּך. שינויים משפיעים על כל הלקוחות. גָבוֹהַ. שינויים משפיעים רק על יישום לקוח אחד.

יישום מעשי (Node.js/Express)

כדי להבין איך זה עובד בפועל, בואו נכתוב דוגמה פשוטה של ​​Node.js.

תאר לעצמך שיש לנו שני מיקרו-שירותים הפועלים באופן פנימי:

  • שירות משתמש (מחזיר מידע בסיסי על פרופיל משתמש)
  • שירות הזמנות (מחזיר רשימה של הזמנות עם פירוט מלא)

אנחנו רוצים לבנות BFF אינטרנט וMobile BFF כדי לשרת את האתר שלנו לשולחן העבודה ואת האפליקציה לנייד בצורה שונה.

1. ה-Shared Microservices Mock

ראשית, הנה הנתונים המדומה של שני שירותי המיקרו הבסיסיים שלנו:

// Internal User Service Response
const userProfile = {
    id: 42,
    username: "dev_coder",
    email: "coder@ghaznix.com",
    avatarUrl: "https://ghaznix.com/avatars/42.png",
    preferences: { theme: "light", newsletter: true }
};

// Internal Order Service Response
const orderHistory = [
    { id: "ORD-99", date: "2026-06-25", items: ["Laptop", "Mouse"], status: "Shipped", tax: 15.00, total: 1215.00 },
    { id: "ORD-88", date: "2026-05-12", items: ["Keyboard"], status: "Delivered", tax: 5.00, total: 105.00 }
];

2. The Web BFF (מחזיר מטען מלא מפורט)

ה-Web BFF אוסף את כל השדות מכיוון שבמסך שולחן העבודה יש הרבה מקום להראות אותם:

const express = require('express');
const webBff = express();

webBff.get('/dashboard', (req, res) => {
    // Web needs everything: profile + full order details + settings
    const responsePayload = {
        user: {
            username: userProfile.username,
            email: userProfile.email,
            avatar: userProfile.avatarUrl,
            theme: userProfile.preferences.theme
        },
        orders: orderHistory // Send all order details, taxes, and items
    };
    
    res.json(responsePayload);
});

webBff.listen(3001, () => console.log('Web BFF running on port 3001'));

3. ה-BFF הנייד (החזרות ממוזערות, מטען מצטבר)

ה-BFF הנייד מסנן שדות לא נחוצים (כמו דואר אלקטרוני, הגדרות ומיסים) ומצבר את פריטי ההזמנה כדי לחסוך ברוחב פס:

const express = require('express');
const mobileBff = express();

mobileBff.get('/dashboard', (req, res) => {
    // Mobile only wants: username, avatar, and summary of the latest order
    const latestOrder = orderHistory[0];
    
    const responsePayload = {
        user: {
            username: userProfile.username,
            avatar: userProfile.avatarUrl
        },
        latestOrderStatus: {
            orderId: latestOrder.id,
            status: latestOrder.status,
            date: latestOrder.date,
            itemCount: latestOrder.items.length // Send count instead of array list
        }
    };
    
    res.json(responsePayload);
});

mobileBff.listen(3002, () => console.log('Mobile BFF running on port 3002'));

השוואת גודל מטען

  • גודל תגובה של Web BFF: מכיל תצורה מקוננת, העדפות, רשימת הזמנות מלאה, מיסים, פריטים וכו’ (כ-400 בתים).
  • גודל תגובה של BFF לנייד: מכיל רק 6 זוגות מפתח-ערך המייצגים את הדברים החיוניים. (כ-120 בתים-הפחתה של 70% בגודל הרשת!).

יתרונות וחסרונות של דפוס ה-BFF

למרות שהוא יעיל מאוד, לדפוס ה-BFF יש פשרות:

יתרון (פרו) חסרון (קון)
ביצועי לקוח אופטימליים: לקוחות טוענים רק את הנתונים המדויקים שהם צריכים, מה שמפחית את צריכת הסוללה ושימוש בזיכרון. שכפול קוד: ייתכן שתכתוב לוגיקה דומה של שליפת נתונים במספר בסיסי קוד BFF.
מחזורי שחרור מהירים יותר: צוות החזית הנייד יכול לעדכן את שרת ה-BFF שלו ללא צורך בתיאום עם מפתחי אינטרנט. ספירת שרתים מוגברת: במקום לנהל שער API אחד, כעת עליך לפרוס ולנהל מספר שירותי BFF.
קוד Frontend פשוט: הלקוח אינו צריך לטפל בהיגיון מורכב של מיון, סינון או מיזוג; זה רק מציג את ה-JSON שהוא מקבל. ניהול אבטחה: אישורי SSL/TLS, כללי הגבלת תעריפים וחומות אש חייבים להיות מנוהלים על פני מספר שערים.

מסקנה

דפוס Backend for Frontend (BFF) הוא ארכיטקטורה רבת עוצמה עבור מערכות המשרתות סוגי לקוחות מרובים, כגון מכשירי אינטרנט, ניידים ו-IoT. על ידי יצירת שערים מותאמים עבור כל חזית ספציפית, אתה מנתק את הפיתוח של הלקוח, ממזער את גודל המטען ומספק חווית משתמש מהירה ומגיבה יותר.

אם למערכת שלך יש רק יישום אינטרנט בודד, די בשער API משותף. אבל ברגע שאתה מתחיל לבנות אפליקציות לנייד או חוויות מכשיר מיוחדות לצד אפליקציית האינטרנט שלך, הטמעת BFF היא הדרך הטובה ביותר לשמור על ארכיטקטורות הקצה והקצה האחורי שלך נקיות, אופטימליות ועצמאיות.


גלה עוד פיתוח תוכנה ותובנות הנדסיות עורפיות בבלוג Ghaznix →