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

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

Edge Microgateway v. 2.5.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.<plugin-name>

หากต้องการเพิ่มพารามิเตอร์การกำหนดค่าที่ชื่อ 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

เครื่องบันทึก

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

  • info(object, message)
  • warn(object, message)
  • error(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 โปรดดูข้อมูลเพิ่มเติมในเธรดการสนทนานี้

ระบบได้เพิ่มปลั๊กอินตัวอย่างชื่อ 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 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);
    }

  };

}