คุณกําลังดูเอกสาร Apigee Edge
ดูเอกสารประกอบเกี่ยวกับ Apigee X
Edge Microgateway เวอร์ชัน 2.5.x
ผู้ชม
หัวข้อนี้มีไว้สําหรับนักพัฒนาซอฟต์แวร์ที่ต้องการขยายฟีเจอร์ของ Edge Microgateway โดยการเขียนปลั๊กอินที่กําหนดเอง หากต้องการเขียนปลั๊กอินใหม่ จําเป็นต้องมีประสบการณ์ในการใช้งาน JavaScript และ Node.js
ปลั๊กอิน Edge Microgateway ที่กําหนดเองคืออะไร
ปลั๊กอินคือโมดูล Node.js ที่เพิ่มฟังก์ชันการทํางานของ Edge Microgateway โมดูลปลั๊กอินเป็นไปตามรูปแบบที่สอดคล้องกันและจัดเก็บไว้ในตําแหน่งที่รู้จักกันใน Edge Microgateway เพื่อให้ค้นพบและเรียกใช้โมดูลเหล่านี้ได้โดยอัตโนมัติ คุณจะได้รับปลั๊กอินที่กําหนดไว้ล่วงหน้าหลายรายการเมื่อคุณติดตั้ง Edge Microgateway ซึ่งรวมถึงปลั๊กอินสําหรับการตรวจสอบสิทธิ์ การจับกุม โควต้า และ Analytics โปรดดูคําอธิบายเกี่ยวกับปลั๊กอินเหล่านี้ในหัวข้อใช้ปลั๊กอิน
คุณเพิ่มฟีเจอร์และความสามารถใหม่ใน Microgateway ได้โดยการเขียนปลั๊กอินที่กําหนดเอง Edge Microgateway คือพร็อกซีแบบ Pass-through ที่ปลอดภัยโดยค่าเริ่มต้นซึ่งจะส่งคําขอและการตอบกลับที่ส่งไปยังบริการเป้าหมายโดยไม่เปลี่ยนแปลง เมื่อใช้ปลั๊กอินที่กําหนดเอง คุณจะโต้ตอบแบบเป็นโปรแกรมกับคําขอและการตอบกลับที่ไหลผ่านไมโครเกตเวย์ได้
ตําแหน่งที่จะวางโค้ดปลั๊กอินที่กําหนดเอง
โฟลเดอร์สําหรับปลั๊กอินที่กําหนดเองจะรวมอยู่ในการติดตั้ง 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!" และพิมพ์ลงไปที่เครื่องชําระเงิน
- หาก Edge Microgateway ทํางานอยู่ ให้หยุดทันที
edgemicro stop
-
cd
ไปยังไดเรกทอรีปลั๊กอินที่กําหนดเอง:cd [prefix]/lib/node_modules/edgemicro/plugins
โดยที่
[prefix]
เป็นไดเรกทอรีคํานําหน้าnpm
ตามที่อธิบายไว้ใน "Install Edge Microgateway อยู่ที่ไหน" ในการติดตั้ง Edge Microgateway - สร้างโปรเจ็กต์ปลั๊กอินใหม่ที่ชื่อว่า response-override และ
cd
ให้กับโปรเจ็กต์ดังกล่าว
mkdir response-override && cd response-override
- สร้างโปรเจ็กต์ Node.js ใหม่โดยดําเนินการดังนี้
npm init
Hit หลายๆ ครั้งเพื่อยอมรับค่าเริ่มต้น - ใช้โปรแกรมแก้ไขข้อความเพื่อสร้างไฟล์ใหม่ชื่อ
index.js
- คัดลอกรหัสต่อไปนี้ลงใน
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"); } }; }
- คุณได้สร้างปลั๊กอินแล้ว และต้องเพิ่มลงในการกําหนดค่า Edge Microgateway
เปิดไฟล์
$HOME/.edgemicro/[org]-[env]-config.yaml
โดยที่org
และenv
คือชื่อองค์กร Edge และสภาพแวดล้อมของคุณ - เพิ่มปลั๊กอิน
response-override
ไปยังเอลิเมนต์plugins:sequence
ดังที่แสดงด้านล่าง
... plugins: dir: ../plugins sequence: - oauth - response-override ...
- รีสตาร์ท Edge Microgateway
- เรียก 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
ฟังก์ชัน
ถูกเรียกเมื่อเริ่มต้นคําขอของไคลเอ็นต์ ฟังก์ชันนี้จะเริ่มทํางานเมื่อ 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 ฯลฯ) ต้องเรียกโค้ดเรียกกลับ 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
ตัวบันทึก
ตัวบันทึกของระบบ ตัวบันทึกที่ใช้อยู่ในปัจจุบันจะส่งออกฟังก์ชันเหล่านี้ โดยออบเจ็กต์อาจเป็นสตริง คําขอ 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 }
- 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 ได้โดยใช้วิธีที่ต้องการ (เช่น คุณอาจใช้ตัวแปลง 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()
ไปยังฟังก์ชันถัดไปในห่วงโซ่คําขอ
ก่อนที่จะส่งไปยังเป้าหมายแบ็กเอนด์
โปรดทราบว่าคุณเพิ่มคําสั่งการแก้ไขข้อบกพร่องอีก 1 คําสั่งเพื่อพิมพ์ข้อมูลที่เปลี่ยนรูปแบบเพื่อวัตถุประสงค์ในการแก้ไขข้อบกพร่องได้ เช่น
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 เป็น "จริง" โปรดดูข้อมูลเพิ่มเติมในชุดข้อความนี้
ตัวอย่างปลั๊กอิน
ปลั๊กอินเหล่านี้มาพร้อมกับการติดตั้ง 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); } }; }
การตอบกลับสะสม
ปลั๊กอินนี้จะรวบรวมกลุ่มข้อมูลจากเป้าหมายลงในพร็อพเพอร์ตี้อาร์เรย์ที่แนบกับออบเจ็กต์การตอบกลับ เมื่อได้รับข้อมูลการตอบกลับทั้งหมดแล้ว อาร์เรย์จะต่อกันไปที่บัฟเฟอร์ ซึ่งจะส่งผ่านไปยังปลั๊กอินถัดไปในลําดับ เนื่องจากปลั๊กอินนี้ทํางานตามการตอบกลับ ซึ่งประมวลผลในลําดับย้อนกลับ คุณจึงควรวางตําแหน่งเป็นปลั๊กอินสุดท้ายในลําดับ
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); } }; }