พัฒนาปลั๊กอินที่กำหนดเอง

คุณกำลังดูเอกสารประกอบ Apigee Edge
ไปที่ เอกสารประกอบเกี่ยวกับ Apigee X.
ข้อมูล

Edge Microgateway เวอร์ชัน 3.1.5 ขึ้นไป

ผู้ชม

หัวข้อนี้มีไว้สำหรับนักพัฒนาซอฟต์แวร์ที่ต้องการขยายฟีเจอร์ของ Edge Microgateway ด้วยการเขียน ปลั๊กอินที่กำหนดเอง หากต้องการเขียนปลั๊กอินใหม่ การใช้งาน JavaScript และ Node.js จะเป็นดังนี้ ต้องระบุ

ปลั๊กอิน Edge Microgateway ที่กำหนดเองคืออะไร

ปลั๊กอินคือโมดูล Node.js ที่เพิ่มฟังก์ชันการทำงานให้กับ Edge Microgateway โมดูลปลั๊กอิน ใช้รูปแบบที่สอดคล้องกันและจัดเก็บไว้ในตำแหน่งที่ Edge Microgateway รู้จัก ซึ่งจะทำให้ เพื่อให้ค้นพบได้และทำงานโดยอัตโนมัติ มีปลั๊กอินที่กำหนดไว้ล่วงหน้าหลายรายการ ติดตั้ง Edge Microgateway ซึ่งรวมถึงปลั๊กอินสำหรับการตรวจสอบสิทธิ์ การขัดขวางการเพิ่มขึ้นอย่างรวดเร็ว โควต้า และ Analytics ปลั๊กอินที่มีอยู่เหล่านี้จะอธิบายในหัวข้อใช้ปลั๊กอิน

คุณสามารถเพิ่มคุณลักษณะและความสามารถใหม่ๆ ใน Microgateway โดยเขียน custom ปลั๊กอินต่างๆ โดยค่าเริ่มต้น Edge Microgateway เป็นพร็อกซีแบบส่งผ่านที่ปลอดภัยซึ่ง คำขอและการตอบกลับที่ไม่มีการเปลี่ยนแปลงจากบริการเป้าหมาย ด้วยปลั๊กอินที่กำหนดเอง คุณสามารถ จะโต้ตอบกับคำขอและการตอบกลับที่ไหลผ่านไมโครเกตเวย์แบบเป็นโปรแกรม

ตำแหน่งที่จะวางโค้ดปลั๊กอินที่กำหนดเอง

โฟลเดอร์สำหรับปลั๊กอินที่กำหนดเองจะรวมอยู่ในการติดตั้ง Edge Microgateway ที่นี่:

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

โดยที่ [prefix] คือไดเรกทอรีคำนำหน้า npm ในฐานะ อธิบายไว้ใน "ติดตั้ง Edge Microgateway ที่ไหน" ใน การติดตั้ง Edge ทางไมโคร

คุณสามารถเปลี่ยนไดเรกทอรีปลั๊กอินเริ่มต้นนี้ได้ ดูวิธีค้นหา ปลั๊กอินต่างๆ

การตรวจสอบปลั๊กอินที่กำหนดไว้ล่วงหน้า

ก่อนที่คุณจะพยายามพัฒนาปลั๊กอินของตัวเอง ควรตรวจสอบว่าไม่มีปลั๊กอินใดที่กำหนดไว้ล่วงหน้า ตามความต้องการของคุณ โดยปลั๊กอินเหล่านี้จะอยู่ในส่วนต่อไปนี้

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

โดยที่ [prefix] คือไดเรกทอรีคำนำหน้า npm โปรดดู หรือ "ติดตั้ง Edge Microgateway ที่ไหน" ใน การติดตั้ง Edge ทางไมโคร

โปรดดูรายละเอียดเพิ่มเติมที่กำหนดไว้ล่วงหน้า ปลั๊กอินที่มากับ Edge Microgateway

เขียนปลั๊กอินแบบง่าย

ในส่วนนี้ เราจะแนะนำขั้นตอนที่จำเป็นในการสร้างปลั๊กอินแบบง่าย ปลั๊กอินนี้ ลบล้างข้อมูลการตอบกลับ (ไม่ว่าจะเป็นอะไรก็ตาม) ด้วยสตริง "สวัสดีทุกคน" แล้วสั่งพิมพ์ไปยัง เครื่องปลายทาง

  1. หาก Edge Microgateway ทำงานอยู่ ให้หยุดทันที:
    edgemicro stop
    
  2. cd ไปยังไดเรกทอรีปลั๊กอินที่กำหนดเอง:

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

    โดยที่ [prefix] คือไดเรกทอรีคำนำหน้า npm ตามที่อธิบายไว้ใน " Edge Microgateway ติดตั้งที่ใด" ใน การติดตั้ง Edge ทางไมโคร

  3. สร้างโปรเจ็กต์ปลั๊กอินใหม่ชื่อ response-override และ cd กับ:
    mkdir response-override && cd response-override
    
  4. สร้างโปรเจ็กต์ Node.js ใหม่:
    npm init
    
    กด "ส่งคืน" หลายๆ ครั้งเพื่อยอมรับค่าเริ่มต้น
  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() มีอาร์กิวเมนต์ 3 อาร์กิวเมนต์ ได้แก่ 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 จะดำเนินการกับคำขอ API ที่ระบุ

  • เครื่องจัดการฟังก์ชัน init() แต่ละรายการ (ondata_request, ondata_response ฯลฯ) จะต้องเรียกใช้ Callback next() เมื่อเสร็จสิ้น การประมวลผล หากไม่เรียกใช้ next() การประมวลผลจะหยุดและคำขอ จะหยุด
  • อาร์กิวเมนต์แรกของ next() อาจเป็นข้อผิดพลาดที่ทำให้เกิดคำขอ การประมวลผลเพื่อสิ้นสุด
  • ตัวแฮนเดิล ondata_ และ onend_ ต้องเรียกใช้ next() ด้วยอาร์กิวเมนต์ที่ 2 ซึ่งมีข้อมูลที่จะส่งไปยังเป้าหมาย หรือไคลเอ็นต์ อาร์กิวเมนต์นี้อาจเป็น Null หากปลั๊กอินกำลังบัฟเฟอร์และมีข้อมูลไม่เพียงพอ เปลี่ยนแปลงตัวเองเลย
  • โปรดทราบว่าจะมีการใช้ปลั๊กอินเพียงอินสแตนซ์เดียวเพื่อให้บริการคำขอและการตอบกลับทั้งหมด หากปลั๊กอินต้องการรักษาสถานะตามคำขอไว้ระหว่างการเรียกใช้ ปลั๊กอินสามารถบันทึกสถานะนั้นใน ที่เพิ่มลงในออบเจ็กต์ request ที่ระบุ (req) ซึ่ง อายุการใช้งานคือระยะเวลาของการเรียก API
  • พยายามจับข้อผิดพลาดทั้งหมดและเรียกใช้ next() กับข้อผิดพลาด ไม่สามารถ การเรียกใช้ next() จะทำให้การเรียก API ถูกระงับ
  • โปรดระวังอย่าให้หน่วยความจำรั่วไหลเนื่องจากอาจส่งผลกระทบต่อประสิทธิภาพโดยรวมของ Edge ไมโครเกตเวย์และทำให้ขัดข้องหากหน่วยความจำหมด
  • โปรดใช้โมเดล Node.js อย่างระมัดระวังโดยไม่ต้องทำการประมวลผลข้อมูลหลักใน เนื่องจากเทรดนี้อาจส่งผลเสียต่อประสิทธิภาพของ Edge Microgateway

เกี่ยวกับฟังก์ชันปลั๊กอิน init()

ส่วนนี้จะอธิบายอาร์กิวเมนต์ที่ส่งผ่านไปยังฟังก์ชัน init() config, logger และ สถิติ

การกำหนดค่า

ข้อมูลการกำหนดค่าที่ได้รับจากการผสานไฟล์การกำหนดค่า 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: []
  }

ตัวบันทึก

ตัวบันทึกระบบ ตัวบันทึกที่ใช้งานในปัจจุบันจะส่งออกฟังก์ชันเหล่านี้ โดยที่ออบเจ็กต์ดังกล่าวสามารถ สตริง, คำขอ 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 - จำนวนการตอบกลับทั้งหมด
  • connections - จำนวนการเชื่อมต่อเป้าหมายที่ใช้งานอยู่

เกี่ยวกับฟังก์ชัน next()

เมธอดปลั๊กอินทั้งหมดต้องเรียกใช้ next() เพื่อประมวลผลเมธอดถัดไปใน (หรือกระบวนการของปลั๊กอินจะค้าง) ในวงจรชีวิตของคำขอ วิธีการแรกคือ onrequest() เมธอดถัดไปที่จะถูกเรียกคือเมธอด ondata_request() อย่างไรก็ตาม จะเรียก ondata_request ก็ต่อเมื่อคำขอมีข้อมูล เช่น เช่น คำขอ POST วิธีการถัดไปที่เรียกว่าจะ onend_request() ซึ่งจะถูกเรียกใช้เมื่อการประมวลผลคำขอเสร็จสมบูรณ์ จะเรียกฟังก์ชัน onerror_* ในกรณีที่เกิดข้อผิดพลาดเท่านั้น และช่วยให้คุณสามารถ จัดการข้อผิดพลาดด้วยโค้ดที่กำหนดเองได้ หากต้องการ

สมมติว่าระบบส่งข้อมูลไปในคำขอและมีการเรียกใช้ ondata_request() ประกาศ ที่ฟังก์ชันเรียก next() ด้วยพารามิเตอร์ 2 ตัว ได้แก่

next(null, data);

ตามกฎแล้ว พารามิเตอร์แรกจะใช้เพื่อถ่ายทอดข้อมูลข้อผิดพลาด ซึ่งจากนั้นคุณสามารถ ในฟังก์ชันต่อมาในห่วงโซ่ ตั้งค่าเป็น null ถือว่าผิด ที่เราบอกว่าไม่มีข้อผิดพลาด และการดำเนินการตามคำขอควรจะดำเนินไปตามปกติ ถ้า อาร์กิวเมนต์นี้เป็นจริง (เช่น ออบเจ็กต์ข้อผิดพลาด) คำขอจะหยุดการประมวลผลและคำขอคือ ไปยังเป้าหมาย

พารามิเตอร์ที่ 2 จะส่งข้อมูลคำขอไปยังฟังก์ชันถัดไปในเชน หากไม่ทำเช่นนั้น การประมวลผลเพิ่มเติม จากนั้นระบบจะส่งข้อมูลคำขอโดยไม่มีการเปลี่ยนแปลงไปยังเป้าหมายของ API อย่างไรก็ตาม คุณจะมีโอกาสแก้ไขข้อมูลคำขอภายในวิธีการนี้ และส่งข้อมูลที่แก้ไขแล้ว ไปยังเป้าหมาย ตัวอย่างเช่น หากข้อมูลคำขอเป็น 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. สร้าง 3 ขั้นตอนง่ายๆ ปลั๊กอิน

ลองใช้ปลั๊กอินต่อไปนี้ สิ่งที่ต้องทำคือเอาต์พุตคอนโซลการพิมพ์เมื่อตัวแฮนเดิลเหตุการณ์ โทรหา:

ปลั๊กอิน/ปลั๊กอิน-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);
    }
  };
}

ตอนนี้ ให้พิจารณาสร้างปลั๊กอินเพิ่มอีก 2 รายการ คือ 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 1 ครั้งสำหรับข้อมูลแต่ละกลุ่มที่ มาถึง ในตัวอย่างนี้ (เอาต์พุตที่แสดงด้านล่าง) จะได้รับกลุ่ม 2 กลุ่ม

ต่อไปนี้คือตัวอย่างผลลัพธ์การแก้ไขข้อบกพร่องที่เกิดขึ้นเมื่อใช้งานปลั๊กอินทั้ง 3 นี้และส่งคำขอแล้ว ผ่าน 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 จะส่งไปยังปลั๊กอินเดียวกัน ดังนั้น สถานะของคำขอที่ 2 จากไคลเอ็นต์อื่นจะเขียนทับรายการแรก สถานที่ปลอดภัยแห่งเดียวที่ บันทึกสถานะปลั๊กอินคือการจัดเก็บสถานะไว้ในพร็อพเพอร์ตี้บนออบเจ็กต์คำขอหรือออบเจ็กต์ อายุการใช้งานจำกัดตามจำนวนคำขอ)

การเขียน 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 โปรดดูการสนทนานี้ ชุดข้อความเพื่อดูข้อมูลเพิ่มเติม

มีการเพิ่มปลั๊กอินตัวอย่างชื่อ 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 ทางไมโคร

accumulate-request

ปลั๊กอินนี้จะรวบรวมข้อมูลจากไคลเอ็นต์ลงในพร็อพเพอร์ตี้อาร์เรย์ที่แนบกับ เป็นออบเจ็กต์คำขอ เมื่อได้รับข้อมูลคำขอทั้งหมดแล้ว อาร์เรย์จะต่อเข้ากับบัฟเฟอร์ ซึ่งจะส่งผ่านไปยังปลั๊กอินถัดไปในลำดับ ปลั๊กอินนี้ควรเป็นปลั๊กอินแรก ในลำดับเพื่อให้ปลั๊กอินต่อๆ มาได้รับข้อมูลคำขอที่สะสมไว้

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

ปลั๊กอินนี้จะรวบรวมข้อมูลจากเป้าหมายเป็นพร็อพเพอร์ตี้อาร์เรย์ที่แนบกับ ออบเจ็กต์การตอบกลับ เมื่อได้รับข้อมูลการตอบกลับทั้งหมดแล้ว อาร์เรย์จะต่อเข้ากับบัฟเฟอร์ ซึ่งจะส่งผ่านไปยังปลั๊กอินถัดไปในลำดับ เนื่องจากปลั๊กอินนี้ทำงานบน คำตอบ ซึ่งประมวลผลในลำดับย้อนกลับ คุณควรวางตำแหน่งไว้เป็นปลั๊กอินสุดท้าย ตามลำดับ

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

  };

}