پلاگین های سفارشی را توسعه دهید

شما در حال مشاهده اسناد Apigee Edge هستید.
به مستندات Apigee X بروید .
اطلاعات

Edge Microgateway نسخه 3.3.x

مخاطب

این موضوع برای توسعه دهندگانی در نظر گرفته شده است که می خواهند ویژگی های Edge Microgateway را با نوشتن افزونه های سفارشی گسترش دهند. اگر می خواهید افزونه جدیدی بنویسید، تجربه با جاوا اسکریپت و 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 است همانطور که در "Where is Edge Microgateway installed" در Installing Edge Microgateway توضیح داده شده است.

شما می توانید این فهرست پلاگین پیش فرض را تغییر دهید. به مکان پیدا کردن افزونه ها مراجعه کنید.

بررسی افزونه های از پیش تعریف شده

قبل از اینکه بخواهید افزونه خود را توسعه دهید، خوب است بررسی کنید که هیچ یک از افزونه های از پیش تعریف شده مطابق با نیازهای شما نباشد. این افزونه ها در:

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

جایی که [prefix] دایرکتوری پیشوند npm است. در نصب Edge Microgateway به "Where is installed Microgateway Edge" مراجعه کنید.

برای جزئیات، افزونه های از پیش تعریف شده ارائه شده با Edge Microgateway را نیز ببینید.

یک افزونه ساده بنویسید

در این بخش، مراحل لازم برای ایجاد یک افزونه ساده را طی می کنیم. این افزونه داده های پاسخ (هر چه که باشد) را با رشته "Hello, World!" و آن را در ترمینال چاپ می کند.

  1. اگر Edge Microgateway در حال اجرا است، اکنون آن را متوقف کنید:
    edgemicro stop
    
  2. cd به دایرکتوری پلاگین سفارشی:

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

    جایی که [prefix] دایرکتوری پیشوند npm است همانطور که در "Where is Edge Microgateway installed" در Installing Edge Microgateway توضیح داده شده است.

  3. یک پروژه پلاگین جدید به نام پاسخ-بازنویسی و 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 یک API را فراخوانی کنید. (این فراخوانی 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() یک شی را با کنترل کننده های تابع نامگذاری شده برمی گرداند که زمانی که رویدادهای خاصی در طول عمر یک درخواست رخ می دهند فراخوانی می شوند.

توابع کنترل کننده رویداد

یک افزونه باید برخی یا همه این توابع کنترل کننده رویداد را اجرا کند. اجرای این توابع به عهده شماست. هر تابع داده شده اختیاری است و یک پلاگین معمولی حداقل زیر مجموعه ای از این توابع را پیاده سازی می کند.

درخواست کنترل کننده رویداد جریان

این توابع در صورت درخواست در 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 یک درخواست API داده شده را پردازش می کند، رخ می دهد، فراخوانی می شود.

  • هر یک از کنترل‌کننده‌های تابع init() ( ondata_request ، ondata_response ، و غیره) باید پس از انجام پردازش، callback () next را فراخوانی کنند. اگر next() را فراخوانی نکنید، پردازش متوقف می شود و درخواست متوقف می شود.
  • اولین آرگومان بعدی () ممکن است خطایی باشد که باعث می شود پردازش درخواست خاتمه یابد.
  • کنترل‌کننده‌های ondata_ و onend_ باید next() را با آرگومان دوم حاوی داده‌هایی که باید به هدف یا مشتری ارسال شود فراخوانی کنند. اگر افزونه بافر باشد و داده های کافی برای تبدیل در آن لحظه نداشته باشد، این آرگومان می تواند تهی باشد.
  • توجه داشته باشید که یک نمونه از افزونه برای سرویس دهی به تمام درخواست ها و پاسخ ها استفاده می شود. اگر افزونه ای بخواهد وضعیت هر درخواست را بین تماس ها حفظ کند، می تواند آن حالت را در ویژگی اضافه شده به شی درخواست ارائه شده ( req ) ذخیره کند، که طول عمر آن مدت تماس API است.
  • مراقب باشید که همه خطاها را بگیرید و با خطای next() را فراخوانی کنید. عدم تماس با next() منجر به قطع تماس API خواهد شد.
  • مراقب باشید که نشت حافظه را معرفی نکنید زیرا می تواند بر عملکرد کلی Edge Microgateway تأثیر بگذارد و در صورت تمام شدن حافظه باعث خرابی آن شود.
  • مراقب باشید از مدل Node.js پیروی کنید و وظایف محاسباتی فشرده را در رشته اصلی انجام ندهید زیرا این کار می تواند بر عملکرد Edge Microgateway تأثیر منفی بگذارد.

درباره تابع init() افزونه

این بخش آرگومان های ارسال شده به تابع init() را شرح می دهد: config ، logger و stats .

پیکربندی

داده های پیکربندی به دست آمده از ادغام فایل پیکربندی Edge Microgateway با داده های دانلود شده از Apigee Edge در یک شی به نام: config قرار می گیرد.

برای افزودن یک پارامتر پیکربندی به نام param با مقدار foo به افزونه‌ای به نام answer-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);
    },

در این مورد، در خروجی اشکال زدایی افزونه، مواردی را مشاهده خواهید کرد:

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

می‌توانید به پیکربندی microgateway ادغام شده و داده‌های 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: []
  }

چوب بر

لاگر سیستم. لاگر مورد استفاده در حال حاضر این توابع را صادر می کند، جایی که شی می تواند یک رشته، درخواست 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
  }
  
  • درخواست ها - تعداد کل درخواست ها.
  • پاسخ ها - تعداد کل پاسخ ها.
  • اتصالات - تعداد اتصالات هدف فعال.

در مورد تابع next()

همه متدهای افزونه باید next() را فراخوانی کنند تا پردازش متد بعدی در این سری ادامه یابد (در غیر این صورت فرآیند پلاگین متوقف خواهد شد). در چرخه عمر درخواست، اولین متد فراخوانی شده onrequest () است. متد بعدی که فراخوانی می شود متد ondata_request() است. با این حال، ondata_request فقط در صورتی فراخوانی می شود که درخواست شامل داده باشد، برای مثال در مورد درخواست POST. متد بعدی فراخوانی شده onend_request() است که پس از تکمیل پردازش درخواست فراخوانی می شود. توابع onerror_* فقط در صورت بروز خطا فراخوانی می شوند و در صورت تمایل به شما این امکان را می دهند که خطاها را با کد سفارشی مدیریت کنید.

فرض کنید داده ها در درخواست ارسال می شوند و ondata_request() فراخوانی می شود. توجه داشته باشید که تابع next() با دو پارامتر فراخوانی می کند:

next(null, data);

طبق قرارداد، اولین پارامتر برای انتقال اطلاعات خطا استفاده می شود، که سپس می توانید آن را در یک تابع بعدی در زنجیره مدیریت کنید. با تنظیم آن بر روی null ، یک آرگومان نادرست، می گوییم هیچ خطایی وجود ندارد و پردازش درخواست باید به طور معمول ادامه یابد. اگر این آرگومان درست باشد (مانند یک شی Error)، پردازش درخواست متوقف می شود و درخواست به هدف ارسال می شود.

پارامتر دوم داده های درخواست را به تابع بعدی در زنجیره ارسال می کند. اگر پردازش اضافی انجام ندهید، داده‌های درخواست بدون تغییر به هدف API ارسال می‌شوند. با این حال، شما این شانس را دارید که داده های درخواست را در این روش تغییر دهید و درخواست اصلاح شده را به هدف ارسال کنید. به عنوان مثال، اگر داده‌های درخواست XML هستند و هدف مورد نظر JSON را انتظار دارد، می‌توانید کدی را به متد ondata_request() اضافه کنید که (a) Content-Type هدر درخواست را به 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() به تابع بعدی در زنجیره درخواست ارسال می‌شوند، قبل از اینکه به هدف Backend ارسال شوند.

توجه داشته باشید که می توانید دستور اشکال زدایی دیگری را برای چاپ داده های تبدیل شده برای اهداف اشکال زدایی اضافه کنید. به عنوان مثال:

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. سه پلاگین ساده ایجاد کنید

افزونه زیر را در نظر بگیرید. تنها کاری که انجام می دهد این است که خروجی کنسول را زمانی که کنترل کننده رویداد آن فراخوانی می شود چاپ می کند:

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 کنترل کننده‌های رویداد هستند که در زمان‌های خاصی در طول پردازش درخواست و پاسخ اجرا می‌شوند. به عنوان مثال، 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 را روی true تنظیم کرده اید، برای اطلاعات بیشتر به این موضوع بحث مراجعه کنید.

حذف شده در: v3.3.3

نمونه پلاگین به نام eurekaclient در نسخه 3.3.3 از Edge Microgateway حذف شد. به یادداشت های انتشار مراجعه کنید.

حذف این ویژگی بر عملکرد اصلی microgateway Edge یا بازنویسی URL های هدف تأثیری نمی گذارد. می‌توانید جستجوی نقطه پایانی پویا را پیکربندی کنید و متغیرهای هدف مانند req.targetHostname ، req.targetPath ، req.targetPort و req.targetSecure را در سطح افزونه نادیده بگیرید. به بازنویسی URL های هدف در افزونه ها مراجعه کنید.


نمونه پلاگین ها

این افزونه ها با نصب Edge Microgateway شما ارائه می شوند. می توانید آنها را در نصب Edge Microgateway در اینجا پیدا کنید:

[prefix]/lib/node_modules/edgemicro/plugins

جایی که [prefix] دایرکتوری پیشوند npm است همانطور که در "Where is Edge Microgateway installed" در 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);
    }

  };

}