คุณกำลังดูเอกสารประกอบของ Apigee Edge
ไปที่เอกสารประกอบของ Apigee X ข้อมูล
Edge Microgateway เวอร์ชัน 3.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/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
เขียนปลั๊กอินง่ายๆ
ในส่วนนี้ เราจะแนะนำขั้นตอนที่จำเป็นในการสร้างปลั๊กอินง่ายๆ ปลั๊กอินนี้จะลบล้างข้อมูลการตอบกลับ (ไม่ว่าจะในรูปแบบใดก็ตาม) ด้วยสตริง "สวัสดีทุกคน" และสั่งพิมพ์ไปยังเทอร์มินัล
- หาก Edge Microgateway ทำงานอยู่ ให้หยุดการทำงานทันที
edgemicro stop
-
cd
ไปยังไดเรกทอรีปลั๊กอินที่กำหนดเอง:cd [prefix]/lib/node_modules/edgemicro/plugins
โดยที่
[prefix]
คือไดเรกทอรีคำนำหน้าnpm
ตามที่อธิบายใน " Edge Microgateway ได้รับการติดตั้งไว้ไว้ที่ใด" ใน การติดตั้ง Edge Microgateway - สร้างโปรเจ็กต์ปลั๊กอินใหม่ที่ชื่อว่า response-override และ
cd
ไปยังโปรเจ็กต์ดังกล่าว
mkdir response-override && cd response-override
- สร้างโปรเจ็กต์ Node.js ใหม่:
npm init
กด Return หลายๆ ครั้งเพื่อยอมรับค่าเริ่มต้น - ใช้เครื่องมือแก้ไขข้อความเพื่อสร้างไฟล์ใหม่ที่ชื่อ
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
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
หากต้องการเพิ่มพารามิเตอร์การกำหนดค่าที่ชื่อ 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: [] }
logger
ตัวบันทึกระบบ ตัวบันทึกที่ใช้งานอยู่จะส่งออกฟังก์ชันเหล่านี้ โดยที่ออบเจ็กต์อาจเป็นสตริง, คำขอ HTTP, การตอบกลับ HTTP หรืออินสแตนซ์ข้อผิดพลาด
info(object, message)
warn(object, message)
error(object, message)
trace(object, message)
debug(object, message)
สถิติ
ออบเจ็กต์ที่มีจำนวนคำขอ การตอบกลับ ข้อผิดพลาด และสถิติรวมอื่นๆ ที่เกี่ยวข้องกับคำขอและการตอบกลับที่ไหลผ่านอินสแตนซ์ไมโครเกตเวย์
- treqErrors - จำนวนคำขอเป้าหมายที่มีข้อผิดพลาด
- treqErrors - จำนวนการตอบกลับเป้าหมายที่มีข้อผิดพลาด
- statusCodes - ออบเจ็กต์ที่มีจำนวนโค้ดตอบกลับ:
{ 1: number of target responses with 1xx response codes 2: number of target responses with 2xx response codes 3: number of target responses with 3xx response codes 4: number of target responses with 4xx response codes 5: number of target responses with 5xx response codes }
- requests - จำนวนคำขอทั้งหมด
- Responses - จำนวนคำตอบทั้งหมด
- Connections - จำนวนการเชื่อมต่อเป้าหมายที่ใช้งานอยู่
เกี่ยวกับฟังก์ชัน next()
เมธอดปลั๊กอินทั้งหมดต้องเรียกใช้ next()
เพื่อประมวลผลเมธอดถัดไปในชุดต่อ (ไม่เช่นนั้นกระบวนการปลั๊กอินจะค้าง) ในวงจรของคำขอ วิธีแรกที่จะเรียกใช้คือ onrequest() และเมธอดถัดไปที่จะเรียกใช้คือเมธอด ondata_request()
แต่ระบบจะเรียกใช้ ondata_request
ก็ต่อเมื่อคำขอมีข้อมูล เช่น ในกรณีของคำขอ POST เท่านั้น วิธีการถัดไปที่เรียกคือ onend_request()
ซึ่งจะเรียกใช้เมื่อการประมวลผลคำขอเสร็จสมบูรณ์ ระบบจะเรียกใช้ฟังก์ชัน onerror_*
ในกรณีที่เกิดข้อผิดพลาดเท่านั้น และให้คุณจัดการข้อผิดพลาดด้วยรหัสที่กำหนดเองได้ หากต้องการ
สมมติว่ามีการส่งข้อมูลในคำขอ แล้วเรียก ondata_request()
โปรดสังเกตว่าฟังก์ชันดังกล่าวเรียกใช้ next()
ด้วยพารามิเตอร์ 2 รายการ ดังนี้
next(null, data);
ตามแบบแผน พารามิเตอร์แรกจะใช้เพื่อถ่ายทอดข้อมูลข้อผิดพลาด ซึ่งคุณสามารถจัดการในฟังก์ชันต่อๆ ไปในเชนได้ หากตั้งค่าเป็น null
ซึ่งเป็นอาร์กิวเมนต์ที่ไม่ถูกต้อง เราจะบอกว่าไม่มีข้อผิดพลาด และการดำเนินการตามคำขอควรดำเนินการตามปกติ หากอาร์กิวเมนต์นี้เชื่อถือได้ (เช่น ออบเจ็กต์ข้อผิดพลาด) ระบบจะหยุดการประมวลผลคำขอ และระบบจะส่งคำขอไปยังเป้าหมาย
พารามิเตอร์ที่สองจะส่งข้อมูลคำขอไปยังฟังก์ชันถัดไปในเชน หากคุณไม่ประมวลผลเพิ่มเติม ระบบจะส่งข้อมูลคำขอไปยังเป้าหมายของ 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. ตรวจสอบผลลัพธ์การแก้ไขข้อบกพร่อง
ต่อไปเรามาดูเอาต์พุตที่จะเกิดขึ้นเมื่อมีการเรียกปลั๊กอินเหล่านี้กัน โดยมีเรื่องสำคัญ 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 เป้าหมายใหม่ในปลั๊กอิน
เพิ่มแล้วใน 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); } }; }
คำตอบสะสม
ปลั๊กอินนี้จะรวบรวมชิ้นส่วนข้อมูลจากเป้าหมายลงในพร็อพเพอร์ตี้อาร์เรย์ที่แนบอยู่กับออบเจ็กต์ Response เมื่อได้รับข้อมูลคำตอบทั้งหมดแล้ว อาร์เรย์จะเชื่อมต่ออยู่ในบัฟเฟอร์ซึ่งจะส่งไปยังปลั๊กอินถัดไปในลำดับ เนื่องจากปลั๊กอินนี้ทำงานบนคำตอบ ซึ่งจะได้รับการประมวลผลแบบย้อนกลับ คุณจึงควรจัดตำแหน่งปลั๊กอินนี้เป็นปลั๊กอินสุดท้ายในลำดับ
module.exports.init = function(config, logger, stats) { function accumulate(res, data) { if (!res._chunks) res._chunks = []; res._chunks.push(data); } return { ondata_response: function(req, res, data, next) { if (data && data.length > 0) accumulate(res, data); next(null, null); }, onend_response: function(req, res, data, next) { if (data && data.length > 0) accumulate(res, data); var content = Buffer.concat(res._chunks); delete res._chunks; next(null, content); } }; }
ปลั๊กอินส่วนหัวตัวพิมพ์ใหญ่
การกระจาย Edge Microgateway มีตัวอย่างปลั๊กอินที่ชื่อว่า <microgateway-root-dir>/plugins/header-uppercase
โดยตัวอย่างจะมีความคิดเห็นที่อธิบายเครื่องจัดการฟังก์ชันแต่ละตัว ตัวอย่างนี้แปลงข้อมูลอย่างง่ายของการตอบสนองเป้าหมายและเพิ่มส่วนหัวที่กำหนดเองไปยังคำขอของไคลเอ็นต์และการตอบสนองเป้าหมาย
นี่คือซอร์สโค้ดของ <microgateway-root-dir>/plugins/header-uppercase/index.js
'use strict'; var debug = require('debug')('plugin:header-uppercase'); // required module.exports.init = function(config, logger, stats) { var counter = 0; return { // indicates start of client request // request headers, url, query params, method should be available at this time // request processing stops (and a target request is not initiated) if // next is called with a truthy first argument (an instance of Error, for example) onrequest: function(req, res, next) { debug('plugin onrequest'); req.headers['x-foo-request-id'] = counter++; req.headers['x-foo-request-start'] = Date.now(); next(); }, // indicates start of target response // response headers and status code should be available at this time onresponse: function(req, res, next) { debug('plugin onresponse'); res.setHeader('x-foo-response-id', req.headers['x-foo-request-id']); res.setHeader('x-foo-response-time', Date.now() - req.headers['x-foo-request-start']); next(); }, // chunk of request body data received from client // should return (potentially) transformed data for next plugin in chain // the returned value from the last plugin in the chain is written to the target ondata_request: function(req, res, data, next) { debug('plugin ondata_request ' + data.length); var transformed = data.toString().toUpperCase(); next(null, transformed); }, // chunk of response body data received from target // should return (potentially) transformed data for next plugin in chain // the returned value from the last plugin in the chain is written to the client ondata_response: function(req, res, data, next) { debug('plugin ondata_response ' + data.length); var transformed = data.toString().toUpperCase(); next(null, transformed); }, // indicates end of client request onend_request: function(req, res, data, next) { debug('plugin onend_request'); next(null, data); }, // indicates end of target response onend_response: function(req, res, data, next) { debug('plugin onend_response'); next(null, data); }, // error receiving client request onerror_request: function(req, res, err, next) { debug('plugin onerror_request ' + err); next(); }, // error receiving target response onerror_response: function(req, res, err, next) { debug('plugin onerror_response ' + err); next(); }, // indicates client connection closed onclose_request: function(req, res, next) { debug('plugin onclose_request'); next(); }, // indicates target connection closed onclose_response: function(req, res, next) { debug('plugin onclose_response'); next(); } }; }
เปลี่ยนรูปแบบอักษรตัวพิมพ์ใหญ่
นี่คือปลั๊กอินการเปลี่ยนรูปแบบทั่วไปที่คุณแก้ไขเพื่อทำการเปลี่ยนรูปแบบใดก็ได้ที่ต้องการ ตัวอย่างนี้ เพียงแค่เปลี่ยนการตอบกลับและข้อมูลคำขอเป็นตัวพิมพ์ใหญ่
*/ module.exports.init = function(config, logger, stats) { // perform content transformation here // the result of the transformation must be another Buffer function transform(data) { return new Buffer(data.toString().toUpperCase()); } return { ondata_response: function(req, res, data, next) { // transform each chunk as it is received next(null, data ? transform(data) : null); }, onend_response: function(req, res, data, next) { // transform accumulated data, if any next(null, data ? transform(data) : null); }, ondata_request: function(req, res, data, next) { // transform each chunk as it is received next(null, data ? transform(data) : null); }, onend_request: function(req, res, data, next) { // transform accumulated data, if any next(null, data ? transform(data) : null); } }; }