פיתוח יישומי פלאגין מותאמים אישית

אתם צופים במסמכי התיעוד של Apigee Edge.
כדאי לעיין במסמכי התיעוד של Apigee X.
מידע

Edge Microgateway מגרסה 3.1.5 ואילך

קהל

הנושא הזה מיועד למפתחים שרוצים להרחיב את התכונות של Edge Microgateway באמצעות כתיבה של תוספים בהתאמה אישית. אם רוצים לכתוב פלאגין חדש, צריך ניסיון ב-JavaScript וב-Node.js.

מהו פלאגין מותאם אישית של Edge Microgateway?

תוסף הוא מודול Node.js שמוסיף פונקציונליות ל-Edge Microgateway. מודולים של תוספים פועלים לפי דפוס עקבי ונשמרים במיקום שמוכר ל-Edge Microgateway, כך שהמערכת יכולה לגלות אותם ולהפעיל אותם באופן אוטומטי. כשמתקינים את Edge Microgateway, מסופקים כמה פלאגינים מוגדרים מראש. הם כוללים תוספים לאימות, למניעת עליות פתאומיות בנפח התנועה, למכסות ולניתוח נתונים. פלאגינים קיימים מתוארים במאמר שימוש בפלאגינים.

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

איפה צריך להוסיף קוד של פלאגין בהתאמה אישית

תיקייה של תוספים בהתאמה אישית כלולה כחלק מההתקנה של Edge Microgateway כאן:

[prefix]/lib/node_modules/edgemicro/node_modules/microgateway-plugins

כאשר [prefix] הוא ספריית הקידומת npm כפי שמתואר בקטע 'איפה מותקן Edge Microgateway' במאמר התקנת Edge Microgateway.

אפשר לשנות את ספריית ברירת המחדל הזו של התוספים. איפה אפשר למצוא פלאגינים

בדיקת הפלאגינים המוגדרים מראש

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

[prefix]/lib/node_modules/edgemicro/node_modules/microgateway-plugins

כאשר [prefix] הוא ספריית התחילית npm. אפשר לעיין גם בקטע 'איפה מותקן Edge Microgateway' במאמר התקנת Edge Microgateway.

פרטים נוספים זמינים גם במאמר בנושא תוספים מוגדרים מראש שזמינים ב-Edge Microgateway.

כתיבת פלאגין פשוט

בקטע הזה נסביר איך ליצור תוסף פשוט. התוסף הזה מחליף את נתוני התגובה (לא משנה מה הם) במחרוזת Hello, World!‎ ומדפיס אותה במסוף.

  1. אם Edge Microgateway פועל, צריך להפסיק אותו:
    edgemicro stop
  2. cd לספריית הפלאגינים המותאמת אישית:

    cd [prefix]/lib/node_modules/edgemicro/plugins

    כאשר [prefix] הוא ספריית הקידומת npm, כמו שמתואר במאמר 'איפה מותקן Edge Microgateway' בקטע התקנת Edge Microgateway.

  3. יוצרים פרויקט פלאגין חדש בשם response-override ומוסיפים לו את cd:
    mkdir response-override && cd response-override
  4. יוצרים פרויקט חדש ב-Node.js:
    npm init
    לוחצים כמה פעמים על Return כדי לאשר את ברירות המחדל.
  5. משתמשים בעורך טקסט כדי ליצור קובץ חדש בשם index.js.
  6. מעתיקים את הקוד הבא ל-index.js ושומרים את הקובץ.
    'use strict';
    var debug = require('debug')
    
    module.exports.init = function(config, logger, stats) {
    
      return {
       
        ondata_response: function(req, res, data, next) {
          debug('***** plugin ondata_response');
          next(null, null);
        },
        
        onend_response: function(req, res, data, next) {
          debug('***** plugin onend_response');
          next(null, "Hello, World!\n\n");
        }
      };
    }
  7. עכשיו יצרתם פלאגין, ואתם צריכים להוסיף אותו להגדרות של Edge Microgateway. פותחים את הקובץ $HOME/.edgemicro/[org]-[env]-config.yaml, כאשר org ו-env הם השמות של הארגון והסביבה ב-Edge.
  8. מוסיפים את הפלאגין response-override לרכיב plugins:sequence, כמו שמוצג למטה.
          ...
          
          plugins:
            dir: ../plugins
            sequence:
              - oauth
              - response-override
              
          ...
  9. מפעילים מחדש את Edge Microgateway.
  10. שליחת קריאה ל-API דרך Edge Microgateway. (הקריאה הזו ל-API מניחה שהגדרתם את אותה תצורה כמו במדריך עם אבטחת מפתח API, כפי שמתואר במאמר הגדרה וקביעת תצורה של Edge Microgateway:
    curl -H 'x-api-key: uAM4gBSb6YoMvTHfx5lXJizYIpr5Jd' http://localhost:8000/hello/echo
    Hello, World!

המבנה של פלאגין

התוסף לדוגמה הבא של Edge Microgateway ממחיש את התבנית שצריך לפעול לפיה כשמפתחים תוספים משלכם. קוד המקור של תוסף לדוגמה שמוסבר בקטע הזה נמצא בplugins/header-uppercase/index.js.

  • תוספים הם מודולים רגילים של NPM עם package.json ו-index.js בתיקיית הבסיס.
  • פלאגין חייב לייצא פונקציית init()‎.
  • הפונקציה init()‎ מקבלת שלושה ארגומנטים: config,‏ logger ו-stats. הארגומנטים האלה מתוארים בארגומנטים של הפונקציה Plugin init().
  • הפונקציה init() מחזירה אובייקט עם handlers של פונקציות בעלות שם שמופעלות כשאירועים מסוימים מתרחשים במהלך מחזור החיים של בקשה.

פונקציות של גורם מטפל באירועים

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

בקשה של הגורמים שמטפלים באירועים של זרימת הבקשות

הפונקציות האלה נקראות אירועי בקשה ב-Edge Microgateway.

  • onrequest
  • ondata_request
  • onend_request
  • onclose_request
  • onerror_request

onrequest function

הפונקציה נקראת בתחילת בקשת הלקוח. הפונקציה הזו מופעלת כש-Edge Microgateway מקבל את הבייט הראשון של הבקשה. הפונקציה הזו מאפשרת לכם לגשת לכותרות הבקשה, לכתובת ה-URL, לפרמטרים של השאילתה ולשיטת ה-HTTP. אם קוראים לפונקציה next עם ארגומנט ראשון שהוא ערך אמת (לדוגמה, מופע של Error), עיבוד הבקשה נפסק ולא מתבצעת בקשת יעד.

דוגמה:

onrequest: function(req, res, next) {
      debug('plugin onrequest');
      req.headers['x-foo-request-start'] = Date.now();
      next();
    }

ondata_request function

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

דוגמה:

ondata_request: function(req, res, data, next) {
      debug('plugin ondata_request ' + data.length);
      var transformed = data.toString().toUpperCase();
      next(null, transformed);
    }

onend_request function

הפונקציה מופעלת כשכל נתוני הבקשה מתקבלים מהלקוח.

דוגמה:

onend_request: function(req, res, data, next) {
      debug('plugin onend_request');
      next(null, data);
    }

onclose_request function

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

דוגמה:

onclose_request: function(req, res, next) {
      debug('plugin onclose_request');
      next();
    }

onerror_request function

הפונקציה מופעלת אם יש שגיאה בקבלת בקשת הלקוח.

דוגמה:

onerror_request: function(req, res, err, next) {
      debug('plugin onerror_request ' + err);
      next();
    }

גורמים מטפלים באירועים בתהליך התגובה

הפונקציות האלה מופעלות באירועי תגובה ב-Edge Microgateway.

  • onresponse
  • ondata_response
  • onend_response
  • onclose_response
  • onerror_response

onresponse function

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

דוגמה:

onresponse: function(req, res, next) {      
    debug('plugin onresponse');     
    res.setHeader('x-foo-response-time', Date.now() - req.headers['x-foo-request-start'])    
    next();    
}


ondata_response function

הפונקציה מופעלת כשמתקבל נתח נתונים מהיעד.

דוגמה:

ondata_response: function(req, res, data, next) {
      debug('plugin ondata_response ' + data.length);
      var transformed = data.toString().toUpperCase();
      next(null, transformed);
    }


onend_response function

הפונקציה מופעלת כשכל נתוני התגובה מתקבלים מהיעד.

דוגמה:

onend_response: function(req, res, data, next) {
      debug('plugin onend_response');
      next(null, data);
    }

onclose_response function

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

דוגמה:

onclose_response: function(req, res, next) {
      debug('plugin onclose_response');
      next();
    }


onerror_response function

הפונקציה מופעלת אם יש שגיאה בקבלת תגובת היעד.

דוגמה:

onerror_response: function(req, res, err, next) {
      debug('plugin onerror_response ' + err);
      next();
    }

מה צריך לדעת על פונקציות גורם מטפל באירועים של פלאגינים

פונקציות גורם מטפל באירועים של תוספים מופעלות בתגובה לאירועים ספציפיים שמתרחשים בזמן ש-Edge Microgateway מעבד בקשת API נתונה.

  • כל אחד מהמטפלים בפונקציה init() (‏ondata_request,‏ ondata_response וכו') צריך לקרוא לקריאה החוזרת next() בסיום העיבוד. אם לא קוראים ל-next(), העיבוד ייפסק והבקשה תיתקע.
  • הארגומנט הראשון של next()‎ יכול להיות שגיאה שתגרום להפסקת עיבוד הבקשה.
  • פונקציות ה-handler‏ ondata_ ו-onend_ צריכות לקרוא ל-next() עם ארגומנט שני שמכיל את הנתונים שיועברו ליעד או ללקוח. הארגומנט הזה יכול להיות null אם התוסף מבצע אחסון זמני ואין לו מספיק נתונים כדי לבצע המרה כרגע.
  • חשוב לזכור שמופע יחיד של התוסף משמש לטיפול בכל הבקשות והתגובות. אם תוסף רוצה לשמור את המצב של כל בקשה בין קריאות, הוא יכול לשמור את המצב הזה במאפיין שנוסף לאובייקט request (req) שסופק, ומשך החיים שלו הוא משך הזמן של הקריאה ל-API.
  • חשוב לזהות את כל השגיאות ולהפעיל את next() עם השגיאה. אם לא תתבצע קריאה ל-next(), הקריאה ל-API תיתקע.
  • חשוב להיזהר שלא ליצור דליפות זיכרון, כי הן עלולות להשפיע על הביצועים הכוללים של Edge Microgateway ולגרום לקריסה שלו אם אין זיכרון פנוי.
  • חשוב לפעול לפי המודל של Node.js ולא לבצע משימות שדורשות הרבה משאבי מחשוב בשרשור הראשי, כי זה עלול להשפיע לרעה על הביצועים של Edge Microgateway.

מידע על הפונקציה init() של הפלאגין

בקטע הזה מוסבר על הארגומנטים שמועברים לפונקציה init()‎: ‏config, ‏logger ו-stats.

config

נתוני ההגדרה שמתקבלים ממיזוג של קובץ ההגדרה של Edge Microgateway עם הנתונים שהורדו מ-Apigee Edge ממוקמים באובייקט בשם: config.

כדי להוסיף פרמטר הגדרה בשם param עם ערך של foo לתוסף בשם response-override, צריך להוסיף את השורה הבאה לקובץ default.yaml:

response-override:
    param: foo

לאחר מכן, תוכלו לגשת לפרמטר בקוד של התוסף, כך:

// Called when response data is received
    ondata_response: function(req, res, data, next) {
      debug('***** plugin ondata_response');
      debug('***** plugin ondata_response: config.param: ' + config.param);
      next(null, data);
    },

במקרה כזה, הפלט של ניפוי הבאגים של הפלאגין יכלול את המחרוזת foo:

Sun, 13 Dec 2015 21:25:08 GMT plugin:response-override ***** plugin ondata_response: config.param: foo

אפשר לגשת להגדרות של המיקרו-שער הממוזג ולנתוני Apigee Edge שהורדו באובייקט הצאצא config.emgConfigs. לדוגמה, אפשר לגשת לנתוני ההגדרה האלה בפונקציה init באופן הבא:

module.exports.init = function(config, logger, stats) {
   let emgconfigs = config.emgConfigs;

דוגמה לנתונים שקובץ emgConfigs מכיל:

{
    edgemicro:
    {
        port: 8000,
        max_connections: 1000,
        config_change_poll_interval: 600,
        logging:
        {
            level: 'error',
            dir: '/var/tmp',
            stats_log_interval: 60,
            rotate_interval: 24,
            stack_trace: false
        },
        plugins: { sequence: [Array] },
        global: { org: 'Your Org', env: 'test' }
    },
    headers:
    {
        'x-forwarded-for': true,
        'x-forwarded-host': true,
        'x-request-id': true,
        'x-response-time': true,
        via: true
    },
    proxies:
    [    {
                max_connections: 1000,
                name: 'edgemicro_delayed',
                revision: '1',
                proxy_name: 'default',
                base_path: '/edgemicro_delayed',
                target_name: 'default',
                url: 'https://httpbin.org/delay/10',
                timeout: 0
            }
    ],
    product_to_proxy: { EdgeMicroTestProduct: [ 'edgemicro-auth','edgemicro_delayed',] },
    product_to_scopes: {prod4: [ 'Admin', 'Guest', 'Student' ] },
    product_to_api_resource: { EdgeMicroTestProduct: [ '/*' ] },
    _hash: 0,
    keys: { key: 'Your key', secret: 'Your key ' },
    uid: 'Internally generated uuid',
    targets: []
  }

כלי לרישום ביומן

הכלי לרישום ביומן המערכת. ה-logger שמופעל כרגע מייצא את הפונקציות האלה, כאשר object יכול להיות מחרוזת, בקשת HTTP, תגובת HTTP או מופע של Error.

  • info(object, message)
  • warn(object, message)
  • error(object, message)
  • trace(object, message)
  • debug(object, message)

נתונים סטטיסטיים

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

  • treqErrors – מספר הבקשות לטירגוט שזוהו בהן שגיאות.
  • treqErrors – מספר התגובות של היעד עם שגיאות.
  • statusCodes – אובייקט שמכיל את מספר הפעמים שקוד תגובה מסוים הוחזר:
{
  1: number of target responses with 1xx response codes
  2: number of target responses with 2xx response codes
  3: number of target responses with 3xx response codes
  4: number of target responses with 4xx response codes
  5: number of target responses with 5xx response codes
  }
  
  • בקשות – המספר הכולל של הבקשות.
  • תשובות – המספר הכולל של התשובות.
  • connections – מספר החיבורים הפעילים ליעד.

מידע על הפונקציה next()‎

כל המתודות של הפלאגין חייבות לקרוא ל-next() כדי להמשיך לעבד את המתודה הבאה בסדרה (אחרת תהליך הפלאגין ייתקע). במחזור החיים של הבקשה, השיטה הראשונה שמופעלת היא onrequest(). השיטה הבאה שמופעלת היא ondata_request(), אבל ondata_request מופעלת רק אם הבקשה כוללת נתונים, כמו במקרה של בקשת POST. המתודה הבאה שתופעל תהיה onend_request(), שמופעלת כשהעיבוד של הבקשה מסתיים. הפונקציות onerror_* מופעלות רק במקרה של שגיאה, והן מאפשרות לכם לטפל בשגיאות באמצעות קוד בהתאמה אישית, אם תרצו.

נניח שהנתונים נשלחים בבקשה, ומתבצעת קריאה ל-ondata_request(). שימו לב שהפונקציה קוראת ל-next() עם שני פרמטרים:

next(null, data);

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

הפרמטר השני מעביר את נתוני הבקשה לפונקציה הבאה בשרשרת. אם לא מבצעים עיבוד נוסף, נתוני הבקשה מועברים ללא שינוי ליעד של ה-API. עם זאת, יש לך אפשרות לשנות את נתוני הבקשה בשיטה הזו ולהעביר את הבקשה ששונתה ליעד. לדוגמה, אם נתוני הבקשה הם בפורמט XML, והיעד מצפה לפורמט JSON, אפשר להוסיף קוד לשיטה ondata_request() ש (א) משנה את Content-Type של כותרת הבקשה ל-application/json וממיר את נתוני הבקשה ל-JSON בכל דרך שרוצים (לדוגמה, אפשר להשתמש בממיר xml2json של Node.js שהתקבל מ-NPM).

כך זה יכול להיראות:

ondata_request: function(req, res, data, next) {
  debug('****** plugin ondata_request');
  var translated_data = parser.toJson(data);
  next(null, translated_data);
},

במקרה כזה, נתוני הבקשה (שמונחים כ-XML) מומרים ל-JSON, והנתונים שעברו טרנספורמציה מועברים דרך next() לפונקציה הבאה בשרשרת הבקשות, לפני שהם מועברים ליעד בקצה העורפי.

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

ondata_request: function(req, res, data, next) {
  debug('****** plugin ondata_request');
  var translated_data = parser.toJson(data);
  debug('****** plugin ondata_response: translated_json: ' + translated_json);
  next(null, translated_data);
},

מידע על סדר ההפעלה של רכיבי handler של תוספים

אם אתם כותבים תוספים ל-Edge Microgateway, אתם צריכים להבין את הסדר שבו מופעלים גורמים מטפלים באירועים של תוספים.

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

הדוגמה הבאה נועדה לעזור לכם להבין את רצף הביצוע הזה.

1. ליצור שלושה פלאגינים פשוטים

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

plugins/plugin-1/index.js

module.exports.init = function(config, logger, stats) {

  return {

    onrequest: function(req, res, next) {
      console.log('plugin-1: onrequest');
      next();
    },

    onend_request: function(req, res, data, next) {
      console.log('plugin-1: onend_request');
      next(null, data);
    },

    ondata_response: function(req, res, data, next) {
      console.log('plugin-1: ondata_response ' + data.length);
      next(null, data);
    },

    onend_response: function(req, res, data, next) {
      console.log('plugin-1: onend_response');
      next(null, data);
    }
  };
}

עכשיו, כדאי ליצור עוד שני תוספים, plugin-2 ו-plugin-3, עם אותו קוד (אבל צריך לשנות את ההצהרות console.log() ל-plugin-2 ול-plugin-3 בהתאמה).

2. בדיקת הקוד של הפלאגין

הפונקציות של התוסף שמיוצאות ב-<microgateway-root-dir>/plugins/plugin-1/index.js הן handlers של אירועים שמופעלים בזמנים ספציפיים במהלך העיבוד של הבקשות והתגובות. לדוגמה, הפונקציה onrequest מופעלת כשמתקבל הבייט הראשון של כותרות הבקשה. לעומת זאת, הפונקציה onend_response מופעלת אחרי שמתקבל הבייט האחרון של נתוני התגובה.

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

3. הוספת הפלאגינים לרצף הפלאגינים

נמשיך עם הדוגמה הזו ונוסיף את הפלאגינים לרצף הפלאגינים בקובץ ההגדרות של Edge Microgateway ‏ (~./edgemicro/config.yaml) באופן הבא. הרצף חשוב. היא מגדירה את הסדר שבו מטפלי הפלאגין יפעלו.

  plugins:
    dir: ../plugins
    sequence:
      - plugin-1
      - plugin-2
      - plugin-3
  

4. בדיקת פלט ניפוי הבאגים

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

  • רצף הפלאגינים בקובץ ההגדרות של Edge Microgateway‏ (~./edgemicro/config.yaml) מציין את הסדר שבו מתבצעת הקריאה ל-event handlers.
  • הפונקציות לטיפול בבקשות מופעלות בסדר עולה (הסדר שבו הן מופיעות ברצף הפלאגין – 1, 2, 3).
  • הפונקציות לטיפול בתגובות נקראות בסדר יורד – 3, 2, 1.
  • הפונקציה ondata_response handler נקראת פעם אחת לכל נתח נתונים שמגיע. בדוגמה הזו (הפלט מוצג בהמשך), מתקבלים שני נתחים.

זו דוגמה לפלט של ניפוי באגים שנוצר כששלושת הפלאגינים האלה נמצאים בשימוש ובקשה נשלחת דרך Edge Microgateway. שימו לב לסדר שבו מתבצעת הקריאה ל-handlers:

  plugin-1: onrequest
  plugin-2: onrequest
  plugin-3: onrequest

  plugin-1: onend_request
  plugin-2: onend_request
  plugin-3: onend_request

  plugin-3: ondata_response 931
  plugin-2: ondata_response 931
  plugin-1: ondata_response 931

  plugin-3: ondata_response 1808
  plugin-3: onend_response

  plugin-2: ondata_response 1808
  plugin-2: onend_response

  plugin-1: ondata_response 1808
  plugin-1: onend_response

סיכום

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

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

מידע על שימוש במשתנים גלובליים בתוספים

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

כתיבה מחדש של כתובות URL של יעדים בתוספים

נוסף בגרסה: v2.3.3

אפשר לשנות את כתובת היעד שמוגדרת כברירת מחדל בתוסף באופן דינמי על ידי שינוי המשתנים האלה בקוד התוסף: req.targetHostname ו-req.targetPath.

נוסף בגרסה: v2.4.x

אפשר גם לשנות את יציאת נקודת הקצה של היעד ולבחור בין HTTP ל-HTTPS. משנים את המשתנים האלה בקוד של הפלאגין: req.targetPort ו-req.targetSecure. כדי לבחור ב-HTTPS, מגדירים את req.targetSecure לערך true. כדי לבחור ב-HTTP, מגדירים אותו לערך false. אם הגדרתם את req.targetSecure כ-true, תוכלו לקרוא מידע נוסף בשרשור הדיון הזה.

תוסף לדוגמה בשם eurekaclient נוסף ל-Edge Microgateway. התוסף הזה מדגים איך להשתמש במשתנים req.targetPort ו-req.targetSecure, וממחיש איך Edge Microgateway יכול לבצע חיפוש דינמי של נקודות קצה באמצעות Eureka בתור קטלוג של נקודות קצה של שירות.


פלאגינים לדוגמה

התוספים האלה מסופקים עם ההתקנה של Edge Microgateway. אפשר למצוא אותם בהתקנה של Edge Microgateway כאן:

[prefix]/lib/node_modules/edgemicro/plugins

כאשר [prefix] הוא ספריית הקידומת npm כפי שמתואר בקטע 'איפה מותקן Edge Microgateway' במאמר התקנת Edge Microgateway.

accumulate-request

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

module.exports.init = function(config, logger, stats) {

  function accumulate(req, data) {

    if (!req._chunks) req._chunks = [];
    req._chunks.push(data);

  }

  return {

    ondata_request: function(req, res, data, next) {

      if (data && data.length > 0) accumulate(req, data);

      next(null, null);

    },


    onend_request: function(req, res, data, next) {

      if (data && data.length > 0) accumulate(req, data);

      var content = null;

      if (req._chunks && req._chunks.length) {

        content = Buffer.concat(req._chunks);

      }

      delete req._chunks;

      next(null, content);

    }

  };

}

accumulate-response

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

module.exports.init = function(config, logger, stats) {

  function accumulate(res, data) {
    if (!res._chunks) res._chunks = [];
    res._chunks.push(data);
  }

  return {

    ondata_response: function(req, res, data, next) {
      if (data && data.length > 0) accumulate(res, data);
      next(null, null);
    },

    onend_response: function(req, res, data, next) {
      if (data && data.length > 0) accumulate(res, data);
      var content = Buffer.concat(res._chunks);
      delete res._chunks;
      next(null, content);
    }

  };

}

הפלאגין header-uppercase

הפצות של Edge Microgateway כוללות פלאגין לדוגמה בשם <microgateway-root-dir>/plugins/header-uppercase. הדוגמה כוללת הערות שמתארות כל אחת מהפונקציות לטיפול בבקשות. בדוגמה הזו מתבצעת טרנספורמציה פשוטה של נתוני התגובה של היעד, ומוספות כותרות מותאמות אישית לבקשת הלקוח ולתגובה של היעד.

זה קוד המקור של <microgateway-root-dir>/plugins/header-uppercase/index.js:

'use strict';

var debug = require('debug')('plugin:header-uppercase');

// required
module.exports.init = function(config, logger, stats) {

  var counter = 0;

  return {

    // indicates start of client request
    // request headers, url, query params, method should be available at this time
    // request processing stops (and a target request is not initiated) if
    // next is called with a truthy first argument (an instance of Error, for example)
    onrequest: function(req, res, next) {
      debug('plugin onrequest');
      req.headers['x-foo-request-id'] = counter++;
      req.headers['x-foo-request-start'] = Date.now();
      next();
    },

    // indicates start of target response
    // response headers and status code should be available at this time
    onresponse: function(req, res, next) {
      debug('plugin onresponse');
      res.setHeader('x-foo-response-id', req.headers['x-foo-request-id']);
      res.setHeader('x-foo-response-time', Date.now() - req.headers['x-foo-request-start']);
      next();
    },

    // chunk of request body data received from client
    // should return (potentially) transformed data for next plugin in chain
    // the returned value from the last plugin in the chain is written to the target
    ondata_request: function(req, res, data, next) {
      debug('plugin ondata_request ' + data.length);
      var transformed = data.toString().toUpperCase();
      next(null, transformed);
    },

    // chunk of response body data received from target
    // should return (potentially) transformed data for next plugin in chain
    // the returned value from the last plugin in the chain is written to the client
    ondata_response: function(req, res, data, next) {
      debug('plugin ondata_response ' + data.length);
      var transformed = data.toString().toUpperCase();
      next(null, transformed);
    },

    // indicates end of client request
    onend_request: function(req, res, data, next) {
      debug('plugin onend_request');
      next(null, data);
    },

    // indicates end of target response
    onend_response: function(req, res, data, next) {
      debug('plugin onend_response');
      next(null, data);
    },

    // error receiving client request
    onerror_request: function(req, res, err, next) {
      debug('plugin onerror_request ' + err);
      next();
    },

    // error receiving target response
    onerror_response: function(req, res, err, next) {
      debug('plugin onerror_response ' + err);
      next();
    },

    // indicates client connection closed
    onclose_request: function(req, res, next) {
      debug('plugin onclose_request');
      next();
    },

    // indicates target connection closed
    onclose_response: function(req, res, next) {
      debug('plugin onclose_response');
      next();
    }

  };

}

transform-uppercase

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

 */
module.exports.init = function(config, logger, stats) {

  // perform content transformation here
  // the result of the transformation must be another Buffer
  function transform(data) {
    return new Buffer(data.toString().toUpperCase());
  }

  return {

    ondata_response: function(req, res, data, next) {
      // transform each chunk as it is received
      next(null, data ? transform(data) : null);
    },

    onend_response: function(req, res, data, next) {
      // transform accumulated data, if any
      next(null, data ? transform(data) : null);
    },

    ondata_request: function(req, res, data, next) {
      // transform each chunk as it is received
      next(null, data ? transform(data) : null);
    },

    onend_request: function(req, res, data, next) {
      // transform accumulated data, if any
      next(null, data ? transform(data) : null);
    }

  };

}