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

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

Edge Microgateway v. 3.3.x

กลุ่มเป้าหมาย

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

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

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

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

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

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

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

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

คุณเปลี่ยนไดเรกทอรีปลั๊กอินเริ่มต้นนี้ได้ ดูตำแหน่งของปลั๊กอิน

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

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

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

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

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

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

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

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

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

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

  3. สร้างโปรเจ็กต์ปลั๊กอินใหม่ชื่อ response-override และ cd ไปที่โปรเจ็กต์นั้น
    mkdir response-override && cd response-override
  4. สร้างโปรเจ็กต์ Node.js ใหม่
    npm init
    กด Return หลายครั้งเพื่อยอมรับค่าเริ่มต้น
  5. ใช้โปรแกรมแก้ไขข้อความเพื่อสร้างไฟล์ใหม่ชื่อ index.js
  6. คัดลอกโค้ดต่อไปนี้ลงใน index.js แล้วบันทึกไฟล์
    'use strict';
    var debug = require('debug')
    
    module.exports.init = function(config, logger, stats) {
    
      return {
       
        ondata_response: function(req, res, data, next) {
          debug('***** plugin ondata_response');
          next(null, null);
        },
        
        onend_response: function(req, res, data, next) {
          debug('***** plugin onend_response');
          next(null, "Hello, World!\n\n");
        }
      };
    }
  7. ตอนนี้คุณได้สร้างปลั๊กอินแล้ว และต้องเพิ่มปลั๊กอินลงในการกำหนดค่า Edge Microgateway เปิดไฟล์ $HOME/.edgemicro/[org]-[env]-config.yaml โดยที่ org และ env คือชื่อองค์กรและสภาพแวดล้อม Edge
  8. เพิ่มปลั๊กอิน response-override ลงในองค์ประกอบ plugins:sequence ดังที่แสดงด้านล่าง
          ...
          
          plugins:
            dir: ../plugins
            sequence:
              - oauth
              - response-override
              
          ...
  9. รีสตาร์ท Edge Microgateway
  10. เรียกใช้ API ผ่าน Edge Microgateway (การเรียก API นี้ถือว่าคุณได้ตั้งค่าเดียวกันกับบทแนะนำที่มีความปลอดภัยของคีย์ API ตามที่อธิบายไว้ในการตั้งค่าและกำหนดค่า Edge Microgateway:
    curl -H 'x-api-key: uAM4gBSb6YoMvTHfx5lXJizYIpr5Jd' http://localhost:8000/hello/echo
    Hello, World!

โครงสร้างของปลั๊กอิน

ปลั๊กอินตัวอย่าง Edge Microgateway ต่อไปนี้แสดงรูปแบบที่ควรทำตามเมื่อ พัฒนาปลั๊กอินของคุณเอง ซอร์สโค้ดของปลั๊กอินตัวอย่างที่กล่าวถึงในส่วนนี้อยู่ ใน plugins/header-uppercase/index.js.

  • ปลั๊กอินคือโมดูล NPM มาตรฐานที่มี package.json และ index.js ในโฟลเดอร์รูท
  • ปลั๊กอินต้องส่งออกฟังก์ชัน init()
  • ฟังก์ชัน init() รับอาร์กิวเมนต์ 3 รายการ ได้แก่ config, logger และ stats อาร์กิวเมนต์เหล่านี้อธิบายไว้ในอาร์กิวเมนต์ฟังก์ชัน Plugin init()
  • init() จะแสดงผลออบเจ็กต์ที่มีตัวแฮนเดิลฟังก์ชันที่มีชื่อซึ่งจะเรียกใช้เมื่อ เกิดเหตุการณ์บางอย่างในอายุการใช้งานของคำขอ

ฟังก์ชันตัวแฮนเดิลเหตุการณ์

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

เครื่องจัดการเหตุการณ์โฟลว์คำขอ

ฟังก์ชันเหล่านี้จะเรียกใช้ในเหตุการณ์คำขอใน Edge Microgateway

  • onrequest
  • ondata_request
  • onend_request
  • onclose_request
  • onerror_request

onrequest function

เรียกใช้เมื่อเริ่มคำขอของไคลเอ็นต์ ฟังก์ชันนี้จะทํางานเมื่อ Edge Microgateway ได้รับไบต์แรกของคําขอ ฟังก์ชันนี้ช่วยให้คุณเข้าถึงส่วนหัวของคำขอ URL, พารามิเตอร์การค้นหา และเมธอด HTTP ได้ หากคุณเรียกใช้ next โดยมีอาร์กิวเมนต์แรกเป็นค่าที่ถือว่าเป็นจริง (เช่น อินสแตนซ์ของ Error) ระบบจะหยุดการประมวลผลคำขอและจะไม่เริ่มคำขอเป้าหมาย

ตัวอย่าง

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

ondata_request function

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

ตัวอย่าง

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

onend_request function

เรียกใช้เมื่อได้รับข้อมูลคำขอทั้งหมดจากไคลเอ็นต์แล้ว

ตัวอย่าง

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

onclose_request ฟังก์ชัน

ระบุว่าการเชื่อมต่อไคลเอ็นต์ปิดแล้ว คุณอาจใช้ฟังก์ชันนี้ในกรณีที่การเชื่อมต่อไคลเอ็นต์ไม่น่าเชื่อถือ ระบบจะเรียกใช้เมื่อปิดการเชื่อมต่อซ็อกเก็ตกับไคลเอ็นต์

ตัวอย่าง

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 function

เรียกใช้เมื่อได้รับกลุ่มข้อมูลจากเป้าหมาย

ตัวอย่าง

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


onend_response function

เรียกใช้เมื่อได้รับข้อมูลการตอบกลับทั้งหมดจากเป้าหมาย

ตัวอย่าง

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

onclose_response ฟังก์ชัน

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

ตัวอย่าง

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


onerror_response function

เรียกใช้หากเกิดข้อผิดพลาดในการรับการตอบกลับเป้าหมาย

ตัวอย่าง

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

สิ่งที่จำเป็นต้องทราบเกี่ยวกับฟังก์ชันตัวแฮนเดิลเหตุการณ์ของปลั๊กอิน

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

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

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

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

การกำหนดค่า

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

คุณ เข้าถึงการกำหนดค่า 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)

สถิติ

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

  • 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
  }
  
  • คำขอ - จำนวนคำขอทั้งหมด
  • responses - จำนวนการตอบกลับทั้งหมด
  • การเชื่อมต่อ - จำนวนการเชื่อมต่อเป้าหมายที่ใช้งานอยู่

เกี่ยวกับฟังก์ชัน 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() ที่ (ก) เปลี่ยน Content-Type ของส่วนหัวคำขอเป็น application/json และแปลงข้อมูลคำขอ เป็น JSON โดยใช้วิธีใดก็ได้ที่คุณต้องการ (เช่น คุณอาจใช้ตัวแปลง xml2json ของ Node.js ที่ได้จาก NPM)

มาดูกันว่าการดำเนินการดังกล่าวอาจมีลักษณะอย่างไร

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

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

โปรดทราบว่าคุณสามารถเพิ่มคำสั่งแก้ไขข้อบกพร่องอีกรายการเพื่อพิมพ์ข้อมูลที่แปลงแล้วเพื่อวัตถุประสงค์ในการแก้ไขข้อบกพร่อง ได้ เช่น

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

เกี่ยวกับลำดับการดำเนินการของตัวแฮนเดิลปลั๊กอิน

หากเขียนปลั๊กอินสำหรับ Edge Microgateway คุณต้องทำความเข้าใจลำดับการเรียกใช้ตัวแฮนเดิลเหตุการณ์ของปลั๊กอิน

สิ่งสำคัญที่ควรทราบคือเมื่อคุณระบุลำดับปลั๊กอินในไฟล์กำหนดค่า Edge Microgateway ตัวแฮนเดิลคำขอจะทำงานตามลำดับจากน้อยไปมาก ขณะที่ตัวแฮนเดิลการตอบกลับจะทำงานตามลำดับจากมากไปน้อย

ตัวอย่างต่อไปนี้ออกแบบมาเพื่อช่วยให้คุณเข้าใจลำดับการดำเนินการนี้

1. สร้างปลั๊กอินอย่างง่าย 3 รายการ

ลองดูปลั๊กอินต่อไปนี้ โดยจะพิมพ์เอาต์พุตของคอนโซลเมื่อมีการเรียกตัวแฮนเดิลเหตุการณ์ ของคอนโซลเท่านั้น

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

ตอนนี้ให้ลองสร้างปลั๊กอินอีก 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 โปรดดูข้อมูลเพิ่มเติมในเธรดการสนทนานี้

นำออกใน: v3.3.3

เราได้นำปลั๊กอินตัวอย่างที่ชื่อ eurekaclient ออกจาก Edge Microgateway ใน v.3.3.3 แล้ว ดูบันทึกประจำรุ่น

การนำฟีเจอร์นี้ออกจะไม่ส่งผลต่อฟังก์ชันหลักของ Edge Microgateway หรือการเขียน URL เป้าหมายใหม่ คุณสามารถกำหนดค่าการค้นหาปลายทางแบบไดนามิกและลบล้าง ตัวแปรเป้าหมาย เช่น req.targetHostname, req.targetPath, req.targetPort และ req.targetSecure ได้ที่ ระดับปลั๊กอิน ดูการเขียน URL เป้าหมายใหม่ในปลั๊กอิน


ปลั๊กอินตัวอย่าง

ปลั๊กอินเหล่านี้มาพร้อมกับการติดตั้ง Edge Microgateway คุณดูได้ในการติดตั้ง Edge Microgateway ที่นี่

[prefix]/lib/node_modules/edgemicro/plugins

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

accumulate-request

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

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

  function accumulate(req, data) {

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

  }

  return {

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

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

      next(null, null);

    },


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

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

      var content = null;

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

        content = Buffer.concat(req._chunks);

      }

      delete req._chunks;

      next(null, content);

    }

  };

}

สะสม-การตอบกลับ

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

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

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

  return {

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

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

  };

}

ปลั๊กอิน header-uppercase

การเผยแพร่ Edge Microgateway มีปลั๊กอินตัวอย่างชื่อ <microgateway-root-dir>/plugins/header-uppercase ตัวอย่างมีความคิดเห็น ที่อธิบายตัวแฮนเดิลฟังก์ชันแต่ละรายการ ตัวอย่างนี้จะทำการแปลงข้อมูลอย่างง่ายของ การตอบกลับเป้าหมาย และเพิ่มส่วนหัวที่กำหนดเองลงในคำขอของไคลเอ็นต์และการตอบกลับเป้าหมาย

นี่คือซอร์สโค้ดสำหรับ <microgateway-root-dir>/plugins/header-uppercase/index.js

'use strict';

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

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

  var counter = 0;

  return {

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

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

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

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

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

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

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

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

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

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

  };

}

transform-uppercase

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

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

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

  return {

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

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

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

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

  };

}