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

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

Edge Microgateway เวอร์ชัน 2.3.x

ผู้ชม

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

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

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

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

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

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

[prefix]/lib/node_modules/edgemicro/plugins

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

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

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

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

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

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

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

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

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

  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 มีคำอธิบายอาร์กิวเมนต์เหล่านี้อยู่ในอาร์กิวเมนต์ของฟังก์ชันปลั๊กอิน init()
  • init() จะแสดงผลออบเจ็กต์ที่มีตัวแฮนเดิลฟังก์ชันที่มีชื่อ ซึ่งมีการเรียกใช้เมื่อเกิดเหตุการณ์บางอย่างขึ้นตลอดอายุของคำขอ

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

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

ตัวแฮนเดิลเหตุการณ์โฟลว์คำขอ

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

  • onrequest
  • ondata_request
  • onend_request
  • onclose_request
  • onerror_request

onrequest function

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

ตัวอย่าง

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

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

ตัวอย่าง

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 ฯลฯ) ต้องเรียกใช้โค้ดเรียกกลับ next() เมื่อประมวลผลเสร็จแล้ว หากคุณไม่เรียกใช้ next() การประมวลผลจะหยุดลงและคำขอจะค้าง
  • อาร์กิวเมนต์แรกไปยัง next() อาจเป็นข้อผิดพลาดที่จะทำให้การประมวลผลคำขอสิ้นสุดลง
  • แฮนเดิล ondata_ และ onend_ ต้องเรียกใช้ next() ด้วยอาร์กิวเมนต์ที่ 2 ที่มีข้อมูลซึ่งจะส่งไปยังเป้าหมายหรือไคลเอ็นต์ อาร์กิวเมนต์นี้อาจเป็นค่าว่างหากปลั๊กอินกำลังบัฟเฟอร์และมีข้อมูลไม่เพียงพอที่จะแปลงในขณะนี้
  • โปรดทราบว่าจะมีปลั๊กอินเพียงอินสแตนซ์เดียวที่ใช้ในการให้บริการคำขอและการตอบกลับทั้งหมด หากปลั๊กอินต้องการคงสถานะตามคำขอไว้ระหว่างการเรียก ปลั๊กอินจะบันทึกสถานะนั้นในพร็อพเพอร์ตี้ที่เพิ่มลงในออบเจ็กต์ request ที่ระบุ (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

logger

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

  • info(object, message)
  • warn(object, message)
  • error(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 ซึ่งเป็นอาร์กิวเมนต์ที่ไม่ถูกต้อง เราจะบอกว่าไม่มีข้อผิดพลาด และการดำเนินการตามคำขอควรดำเนินการตามปกติ หากอาร์กิวเมนต์นี้เชื่อถือได้ (เช่น ออบเจ็กต์ข้อผิดพลาด) ระบบจะหยุดการประมวลผลคำขอ และระบบจะส่งคำขอไปยังเป้าหมาย

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

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

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. ตรวจสอบผลลัพธ์การแก้ไขข้อบกพร่อง

ต่อไปเรามาดูเอาต์พุตที่จะเกิดขึ้นเมื่อมีการเรียกปลั๊กอินเหล่านี้กัน โดยมีเรื่องสำคัญ 2-3 อย่างที่ควรทราบ ดังนี้

  • ลำดับปลั๊กอินที่ไฟล์การกำหนดค่า 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 เป้าหมายใหม่ในปลั๊กอิน

เพิ่มแล้วใน v.2.3.3

คุณลบล้าง URL เป้าหมายเริ่มต้นในปลั๊กอินแบบไดนามิกได้โดยแก้ไขตัวแปรเหล่านี้ในโค้ดปลั๊กอิน: req.targetHostname และ req.targetPath

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

ปลั๊กอินต่อไปนี้จะมาพร้อมกับการติดตั้ง Edge Microgateway โดยคุณสามารถดูการติดตั้ง Edge Microgateway ได้ที่นี่

[prefix]/lib/node_modules/edgemicro/plugins

โดยที่ [prefix] คือไดเรกทอรีคำนำหน้า npm ตามที่อธิบายใน " Edge Microgateway ได้รับการติดตั้งไว้ไว้ที่ใด" ใน การติดตั้ง 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);
    }
  };

คำตอบสะสม

ปลั๊กอินนี้จะรวบรวมชิ้นส่วนข้อมูลจากเป้าหมายลงในพร็อพเพอร์ตี้อาร์เรย์ที่แนบอยู่กับออบเจ็กต์ 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 = null;
      if(res._chunks && res._chunks.length) {
        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);
    }

  };

}

บทแนะนำปลั๊กอินเพิ่มเติม

ดูบทแนะนำเหล่านี้ได้ในบล็อก Apigee