تطوير مكونات إضافية مخصصة

يتم الآن عرض مستندات Apigee Edge.
انتقِل إلى مستندات Apigee X.
المعلومات

Edge Microgateway، الإصدار 3.3.x

الجمهور

هذا الموضوع مخصّص للمطوّرين الذين يريدون توسيع ميزات Edge Microgateway من خلال كتابة مكوّنات إضافية مخصَّصة. إذا أردت كتابة مكوّن إضافي جديد، يجب تجربة استخدام JavaScript وNode.js.

ما هو المكوّن الإضافي المخصص Edge Microgateway؟

المكون الإضافي هو وحدة Node.js التي تضيف وظائف إلى Edge Microgateway. تتبع وحدات المكوّنات الإضافية نمطًا ثابتًا ويتم تخزينها في مكان معروف باسم Edge Microgateway، ما يتيح إمكانية اكتشافها وتشغيلها تلقائيًا. يتم توفير العديد من المكونات الإضافية المحددة مسبقًا عند تثبيت Edge Microgateway. ويتضمن ذلك المكونات الإضافية للمصادقة وتوقفات الحظر والحصة والإحصاءات. يتم توضيح هذه المكوّنات الإضافية الحالية في قسم استخدام المكوّنات الإضافية.

يمكنك إضافة ميزات وإمكانات جديدة إلى البوابة الصغيرة من خلال كتابة مكوّنات إضافية مخصّصة. بشكل تلقائي، يكون Edge Microgateway في الأساس خادمًا وكيلاً آمنًا للتعامل مع الطلبات والاستجابات بدون تغيير إلى ومن الخدمات المستهدفة. باستخدام المكوّنات الإضافية المخصّصة، يمكنك التفاعل آليًا مع الطلبات والردود التي تتدفق من البوابة الصغيرة.

مكان وضع رمز المكون الإضافي المخصص

يتم تضمين مجلّد للمكوّنات الإضافية المخصّصة كجزء من تثبيت Edge Microgateway هنا:

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

حيث يكون [prefix] هو دليل البادئة npm على النحو الموضَّح في القسم "أين يتم تثبيت Edge Microgateway" في المقالة Installing 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" في المقالة Installing 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. يمكنك استدعاء واجهة برمجة تطبيقات من خلال Edge Microgateway. (يفترض طلب البيانات من واجهة برمجة التطبيقات هذا أنك قد أعددت الإعدادات نفسها التي يتضمّنها البرنامج التعليمي باستخدام أمان مفتاح واجهة برمجة التطبيقات، كما هو موضّح في إعداد 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. ويتم وصف هذه الوسيطات في وسيطات الدالة init().
  • تعرض init() كائنًا يتضمّن معالِجات الدوال المُسمّاة التي يتم استدعاءها عند وقوع أحداث معيّنة خلال فترة بقاء الطلب.

وظائف معالج الأحداث

ويجب أن تنفِّذ الإضافة بعض وظائف معالج الأحداث هذه أو جميعها. الأمر متروك لك لتنفيذ هذه الدوال. وتكون أيّ دالة اختيارية اختيارية، وسينفِّذ المكون الإضافي النموذجي مجموعة فرعية على الأقل من هذه الدوال.

معالِجات أحداث تدفق الطلب

ويتم استدعاء هذه الدوال عند الطلب في أحداث الطلب في برنامج Edge Microgateway.

  • onrequest
  • ondata_request
  • onend_request
  • onclose_request
  • onerror_request

onrequest دالة

يتم استدعاء هذا الإجراء في بداية طلب العميل. يتم تنشيط هذه الدالة عند تلقّي البايت الأول من الطلب بواسطة Edge Microgateway. تتيح لك هذه الدالة الوصول إلى عناوين الطلبات وعناوين URL ومَعلمات طلب البحث وطريقة HTTP. في حال طلب البحث التالي باستخدام وسيطة أولى صادقة (مثل مثيل الخطأ)، تتوقف معالجة الطلب ولا يتم بدء طلب مستهدَف.

مثال:

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

ondata_request دالة

يتم استدعاء هذه الدالة عند تلقي مجموعة من البيانات من العميل. تمرير بيانات الطلبات إلى المكوِّن الإضافي التالي في تسلسل المكوِّن الإضافي. ويتم إرسال القيمة المعروضة من المكوِّن الإضافي الأخير في التسلسل إلى الهدف. وفي ما يلي حالة استخدام نموذجية هي تحويل بيانات الطلب قبل إرسالها إلى الوجهة المستهدفة.

مثال:

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

onend_request دالة

يتم استدعاء هذا الإجراء عند تلقّي جميع بيانات الطلب من العميل.

مثال:

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

دالة onclose_request

يشير إلى إنهاء اتصال العميل. يمكنك استخدام هذه الدالة في الحالات التي يكون فيها اتصال العميل غير موثوق. ويتم استدعاءها عند إغلاق اتصال المقبس بالعميل.

مثال:

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

دالة onerror_request

يتم استدعاء هذا الحدث إذا حدث خطأ أثناء تلقي طلب العميل.

مثال:

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

يتم استدعاء هذا الإجراء في بداية الردّ المستهدَف. يتم تنشيط هذه الدالة عند تلقّي البايت الأول من الاستجابة بواسطة 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)

يتم استدعاء هذه الدالة عند تلقي مجموعة من البيانات من الهدف.

مثال:

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


دالة واحدة (onend_response)

يتم استدعاء هذا الإجراء عند تلقّي جميع بيانات الاستجابة من الهدف.

مثال:

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

دالة onclose_response

يشير إلى إغلاق الاتصال الهدف. يمكنك استخدام هذه الدالة في الحالات التي يكون فيها الاتصال الهدف غير موثوق. وتستدعي هذه الطريقة عند إغلاق اتصال المقبس بالهدف.

مثال:

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


دالة واحدة (onerror_response)

يتم استدعاء هذا الحدث إذا حدث خطأ أثناء تلقي الاستجابة المستهدفة.

مثال:

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

ما تحتاج إلى معرفته عن دوال معالج أحداث المكوّن الإضافي

يتم استدعاء وظائف معالج أحداث المكوّنات الإضافية استجابةً لأحداث معيّنة تحدث أثناء معالجة Edge Microgateway لطلب معيّن من واجهة برمجة التطبيقات.

  • يجب أن تؤدي كل من معالِجات الدوال init() (ondata_request وondata_response وما إلى ذلك) إلى استدعاء استدعاء next() عند الانتهاء من المعالجة. إذا لم يتم استدعاء next()، ستتوقف المعالجة وسيتوقف الطلب.
  • قد تكون الوسيطة الأولى إلى next() خطأً يؤدي إلى إنهاء معالجة الطلب.
  • يجب أن يستدعي المعالِجان ondata_ وonend_ next() مع وسيطة ثانية تحتوي على البيانات التي سيتم تمريرها إلى الهدف أو العميل. يمكن أن تكون هذه الوسيطة فارغة إذا كان المكوِّن الإضافي في حالة تخزين مؤقت ولا يحتوي على بيانات كافية لتحويله في الوقت الحالي.
  • تجدر الإشارة إلى أنّه يتم استخدام مثيل واحد من المكوِّن الإضافي لتلبية جميع الطلبات والاستجابات. إذا أراد أحد المكونات الإضافية الاحتفاظ بالحالة لكل طلب بين الطلبات، يمكنه حفظ هذه الحالة في الموقع المُضاف إلى عنصر request المُقدَّم (req)، والذي هو مدة طلب البيانات من واجهة برمجة التطبيقات.
  • احرص على التقاط جميع الأخطاء واستدعاء next() مع ظهور الخطأ. وسيؤدي عدم طلب next() إلى تعليق طلب البيانات من واجهة برمجة التطبيقات.
  • يجب تجنُّب تسرب الذاكرة، لأنّ ذلك قد يؤثر في الأداء العام لميزة 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

مسجّل النظام. يصدِّر المسجِّل المستخدَم حاليًا هذه الدوال، حيث يمكن أن يكون الكائن سلسلة أو طلب HTTP أو استجابة HTTP أو مثيل "خطأ".

  • 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
  }
  
  • requests - إجمالي عدد الطلبات.
  • Responses - إجمالي عدد الردود.
  • عمليات الاتصال - عدد الاتصالات المستهدفة النشطة.

حول الدالة next()

يجب أن تستدعي جميع طرق المكوّنات الإضافية next() لمواصلة معالجة الطريقة التالية في السلسلة (أو سيتم إيقاف عملية المكوّن الإضافي). في دورة حياة الطلب، تكون الطريقة الأولى التي يتم استدعاءها onrequest(). والطريقة التالية المطلوب استدعاءها هي طريقة ondata_request()، ومع ذلك، يتم استدعاء ondata_request فقط إذا كان الطلب يتضمّن بيانات، كما في حالة طلب POST مثلاً. إنّ الطريقة التالية التي يتم استدعاءها هي onend_request()، ويتم استدعاءها عند اكتمال معالجة الطلب. يتم استدعاء الدوال onerror_* فقط في حال حدوث خطأ، وهي تسمح لك بمعالجة الأخطاء باستخدام رموز مخصّصة.

لنفترض أنه تم إرسال البيانات في الطلب، وتم استدعاء ondata_request(). لاحظ أنّ الدالة تستدعي next() بمعلّمتَين:

next(null, data);

حسب الاصطلاح، يتم استخدام المَعلمة الأولى لنقل معلومات الخطأ، والتي يمكنك التعامل معها بعد ذلك في دالة لاحقة في السلسلة. من خلال ضبط السياسة على null، وهي وسيطة مزيّفة، يعني ذلك أنّه ليست هناك أخطاء، ومن المفترض أن تتم معالجة الطلبات كالمعتاد. إذا كانت هذه الوسيطة صحيحة (مثل كائن "خطأ")، يتم إيقاف معالجة الطلب ويتم إرسال الطلب إلى الهدف.

وتمرر المعلمة الثانية بيانات الطلب إلى الدالة التالية في السلسلة. وفي حال عدم إجراء عمليات معالجة إضافية، يتم تمرير بيانات الطلب بدون تغيير إلى هدف واجهة برمجة التطبيقات. ومع ذلك، يمكنك تعديل بيانات الطلب بهذه الطريقة وتمرير الطلب المعدّل إلى الهدف. على سبيل المثال، إذا كانت بيانات الطلب بتنسيق XML، وكان الهدف يتوقّع تنسيق JSON، يمكنك عندئذٍ إضافة رمز إلى طريقة ondata_request() التي (أ) تغيّر نوع المحتوى لعنوان الطلب إلى application/json وتحوِّل بيانات الطلب إلى JSON باستخدام أي وسيلة تريدها (على سبيل المثال، يمكنك استخدام محوِّل Node.js xml2json الذي تم الحصول عليه من 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);
},

لمحة عن ترتيب تنفيذ معالج المكوّن الإضافي

إذا كتبت مكوّنات إضافية لبرنامج Edge Microgateway، ستحتاج إلى فهم ترتيب تنفيذ معالِجات أحداث المكوّنات الإضافية.

من المهم الانتباه إلى أنّه عند تحديد تسلسل للمكوّنات الإضافية في ملف إعداد Edge Microgateway، يتم تنفيذ معالِجات الطلب تصاعديًا، بينما يتم تنفيذ معالِجات الاستجابة بترتيب تنازلي.

تم تصميم المثال التالي لمساعدتك على فهم تسلسل التنفيذ هذا.

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 هي معالِجات أحداث يتم تنفيذها في أوقات محدّدة أثناء معالجة الطلبات والاستجابة. على سبيل المثال، ينفذ 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) ترتيب استدعاء معالِجات الأحداث.
  • يتم استدعاء معالِجات الطلبات بترتيب تصاعدي (بالترتيب الذي تظهر به في تسلسل المكوّن الإضافي: 1، 2، 3).
  • يتم استدعاء معالِجات الاستجابة بترتيب تنازلي -- 3، 2، 1.
  • يتم استدعاء المعالِج ondata_response مرة واحدة لكل مجموعة من البيانات تصل. في هذا المثال (الناتج الموضح أدناه)، يتم تلقي مقطعين.

في ما يلي نموذج ناتج تصحيح الأخطاء الذي يتم إنشاؤه عندما تكون هذه المكوّنات الإضافية الثلاثة قيد الاستخدام ويتم إرسال طلب من خلال Edge Microgateway. لاحظ فقط ترتيب استدعاء المعالجات:

  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

ملخّص

من المهم جدًا معرفة ترتيب استدعاء معالِجات المكوّنات الإضافية عند محاولة تنفيذ وظائف مكوّنات إضافية مخصّصة، مثل تجميع بيانات الطلبات أو الاستجابة وتحويلها.

تذكَّر أنّه يتم تنفيذ معالِجات الطلبات بالترتيب الذي يتم به تحديد المكوّنات الإضافية في ملف الإعداد Edge Microgateway، ويتم تنفيذ معالِجات الاستجابة بترتيب معاكس.

حول استخدام المتغيرات العمومية في المكونات الإضافية

يتم إرسال كل طلب إلى Edge Microgateway إلى النسخة نفسها من المكوِّن الإضافي، وبالتالي، ستحل حالة الطلب الثاني من عميل آخر محل الحالة الأولى. والمكان الآمن الوحيد لحفظ حالة المكوِّن الإضافي هو تخزين الحالة في إحدى السمات في كائن الطلب أو كائن الاستجابة (الذي يقتصر عمره على مدة الطلب).

إعادة كتابة عناوين URL المستهدفة في المكوّنات الإضافية

تمت الإضافة في: v2.3.3

يمكنك إلغاء عنوان URL المستهدف التلقائي في أحد المكوّنات الإضافية ديناميكيًا عن طريق تعديل هذه المتغيّرات في رمز المكوّن الإضافي: req.targetHostname وreq.targetPath.

تمت الإضافة في: v2.4.x

يمكنك أيضًا إلغاء منفذ نقطة النهاية المستهدف والاختيار بين HTTP وHTTPS. عدِّل هذه المتغيّرات في رمز المكوّن الإضافي: req.targetPort وreq.targetSecure. لاختيار HTTPS، اضبط req.targetSecure على true، وبالنسبة إلى HTTP، اضبط القيمة على false. في حال ضبط req.targetSecure على "صحيح"، يمكنك الاطّلاع على سلسلة محادثات المناقشة هذه للحصول على مزيد من المعلومات.

تمت إضافة نموذج مكوّن إضافي يسمى eurekaclient إلى Edge Microgateway. يوضِّح هذا المكوِّن الإضافي كيفية استخدام متغيرَي req.targetPort وreq.targetSecure، ويوضّح كيف يمكن لأداة Edge Microgateway إجراء بحث ديناميكي لنقاط النهاية باستخدام Eureka ككتالوج لنقاط النهاية الخاصة بالخدمة.


نماذج المكوّنات الإضافية

يتم توفير هذه المكوّنات الإضافية مع تثبيت Edge Microgateway. يمكنك العثور عليها من خلال تثبيت Edge Microgateway هنا:

[prefix]/lib/node_modules/edgemicro/plugins

حيث يكون [prefix] هو دليل البادئة npm على النحو الموضَّح في القسم "أين يتم تثبيت Edge Microgateway" في المقالة Installing Edge Microgateway.

تجميع الطلب

يجمع هذا المكوِّن الإضافي أجزاء البيانات من العميل في سمة مصفوفة مرتبطة بكائن الطلب. عند استلام جميع بيانات الطلب، يتم ربط الصفيف في مخزن مؤقت يتم تمريره بعد ذلك إلى المكوِّن الإضافي التالي في التسلسل. يجب أن يكون هذا المكوِّن الإضافي هو المكوّن الإضافي الأول في التسلسل، بحيث تتلقّى المكوّنات الإضافية اللاحقة بيانات الطلبات المجمّعة.

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);

    }

  };

}

تجميع-الاستجابة

يجمع هذا المكوِّن الإضافي أجزاء البيانات من الهدف في سمة مصفوفة مرتبطة بكائن الاستجابة. عند تلقّي جميع بيانات الاستجابة، يتم ربط الصفيف في مخازن مؤقّت يتم تمريره بعد ذلك إلى المكوِّن الإضافي التالي في التسلسل. بما أنّ هذا المكوّن الإضافي يعمل استنادًا إلى الاستجابات التي تتم معالجتها بترتيب عكسي، يجب وضعه كآخر مكوّن إضافي في التسلسل.

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);
    }

  };

}

المكوّن الإضافي الخاص برؤوس الأعمدة الكبيرة

تتضمّن توزيعات 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();
    }

  };

}


تحويل كبير

هذا مكوّن إضافي عام لعملية التحويل يمكنك تعديله لتنفيذ أي نوع من التحويل تريده. يحوّل هذا المثال ببساطة الاستجابة وبيانات الطلب إلى أحرف كبيرة.

 */
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);
    }

  };

}