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

يتم الآن عرض مستندات 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" في المقالة تثبيت Microgateway Edge.

يمكنك تغيير دليل المكوِّن الإضافي التلقائي هذا. اطّلِع على مكان العثور على المكوّنات الإضافية.

مراجعة المكوّنات الإضافية المحددة مسبقًا

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

[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. طلب واجهة برمجة تطبيقات من خلال 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- أنشئ ثلاثة مكونات إضافية بسيطة

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

المكوّنات الإضافية/مكوّنات إضافية: 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 المستهدفة في المكونات الإضافية

تمت الإضافة في: الإصدار 2.3.3

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

تمت الإضافة في: الإصدار 2.4.x

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

تمّت الإزالة في: الإصدار 3.3.3

تمت إزالة النموذج الإضافي المُسمى eurekaclient من Edge Microgateway في الإصدار 3.3.3. يُرجى الاطّلاع على ملاحظات الإصدار.

لا تؤثّر إزالة هذه الميزة في الوظيفة الأساسية لطريقة بوابة Edge المصغّرة أو إعادة كتابة عناوين URL المستهدَفة. يمكنك إعداد البحث الديناميكي عن نقاط النهاية وإلغاء المتغيّرات المستهدفة، مثل req.targetHostname وreq.targetPath وreq.targetPort وreq.targetSecure على مستوى المكوِّن الإضافي. راجع إعادة كتابة عناوين URL المستهدفة في المكوّنات الإضافية.


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

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

[prefix]/lib/node_modules/edgemicro/plugins

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

تجميع-طلب

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

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

  };

}