• בלוג
  • מה אפשר לעשות עם Middlewares

מה אפשר לעשות עם Middlewares

10/11/2018

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

אז אתם יודעים לכתוב תוכניות Express בנוד ואולי גם ראיתם איך נראה קוד של Middleware. אבל... מה אפשר לעשות עם זה? ולמה שתרצו לכתוב אחד לתוכנית שלכם? הנה כמה רעיונות.

1. בקרת גישה לנתיב

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

הקוד הבא מוסיף הגנה כך שאפשר יהיה להיכנס לנתיבים עליהם הוא מופעל רק מכתובות IP מסוימות:

module.exports = function(ips) {
    return function(req, res, next) {
        const remoteIp = req.connection.remoteAddress;
        if (!ips.includes(remoteIp)) {
            next(new Error(`Forbidden. your ip is: ${req.connection.remoteAddress}`));
        }
        next();
    };
}

ובשביל להשתמש בו בפרויקט אקספרס כל שעליכם לעשות הוא להפעיל app.use עם ציון הנתיב לדוגמא:

var whitelistIps = require('./lib/middlewares/whitelist_ips');
app.use('/admin', whitelistIps(['127.0.0.1', '::1']));

2. שליפת מידע ראשוני

אחד השימושים המרכזיים ב Middlewares הוא הכנת מידע כך שקוד הטיפול בבקשה יצטרך לעשות פחות עבודה. דוגמא מוכרת היא urlencoded שמפענח את המידע מ POST request ומייצר לנו Request Body בתור אוביקט. דוגמא נוספת היא מנגנון זיהוי משתמשים שיכין את "המשתמש הנוכחי" בתור משתנה שנוכל לפעול לפיו בהמשך הטיפול בבקשה.

אתם יכולים להשתמש ברעיון הזה ולהרחיב אותו כדי להכין מידע משלכם וכך לקצר את הקוד הבא בשרשרת. הספריה mobile-detect מאפשרת לזהות האם גולש הגיע ממכשיר מובייל (ואם כן מאיזה). כך נשלב אותה בקוד שלנו בתור Middleware:

var MobileDetect = require('mobile-detect');

module.exports = function(req, res, next) {
    const md = new MobileDetect(req.get('User-Agent'));
    res.locals.isMobile = md.phone();
    next();
}

ואם תשלבו חוליה זו באפליקציה שלכם יהיה לכם קל יותר לשלוח תוכן מותאם למובייל מהנתיבים הבאים.

3. שליחת JSON באופן אוטומטי

הרעיון האחרון הוא לא משהו שהייתי משתמש בו באופן גורף אבל לעפמים יכול לעזור, וגם להמחיש את הכח של Middlewares. ביישומי אקספרס הכוללים גם Views אתם תמצאו קוד שנראה כך כדי לשלוח מידע ל View Engine ואיתו לייצר את העמוד:

router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

יהיו מקרים שנרצה להשתמש באותה לוגיקה אבל במקום לייצר את כל ה View, נרצה להחזיר רק את אוביקט המידע בתור JSON לצד הלקוח. בצורה כזאת לקוח יוכל להחליט אם הוא "גולש" לעמוד ומקבל את כל ה View, או רק שולח בקשת Ajax, מקבל מידע ומציג אותו באמצעות JavaScript.

ה Middleware הבא מסתכל על הבקשה ולפי כותרת Accept שלה מחליט האם לדרוס את פונקציית render. דריסה כזאת אומרת שהקוד המקורי יחשוב שהוא פונה ל View Engine אבל למעשה יגיע לקוד שלנו שהשתלט על render ומחליף את יצירת ה View ביצירת JSON יחיד:

module.exports = function(req, res, next) {
    if (req.accepts('html')) {
        return next();
    }

    if (req.accepts('json')) {
        res.render = function(_view, data) {
            res.send(data);
        }
    };

    return next();
}

וברגע שאתם מוסיפים את ה Middleware הזה כל הנתיבים עבורם הוא מופעל יקבלו את ההתנהגות הכפולה: אם יפנו אליהם בשביל לקבל HTML הם ישלחו את ה View, אבל אם יפנו אליהם כדי לקבל JSON הם ישלחו את המידע ששימש ליצירת ה View. שימו לב שזה לא משהו שכדאי ליישם באופן גורף כי הרבה פעמים אתם מעבירים ל View Engine יותר מידע ממה שמוצג על המסך.

יש לכם עוד רעיונות שלא הזכרתי כאן? שתפו ואשמח לשמוע בתגובות.