← MockServer Professional Day 3 • Module 3

Day 3 / Module 3: Proxying (Forward, Web, HTTPS Tunneling with Root CA), Record & Replay, and Interactive Breakpoints

คู่มือพิมพ์เขียวเชิงลึกและการวิเคราะห์ทางเทคนิค: การเปลี่ยน MockServer เป็นด่านตรวจกลางสาย, ถอดรหัส HTTPS ด้วย Root CA, สกัดทราฟฟิกจริงสู่ Mocks และการดักแก้ไข Payload กลางอากาศ

[1] ส่วนที่ 1: หมุดเชื่อมโยง & Roadmap Progress Tracker

Day Tracker: 3/6

ชื่อบท/หัวข้อหลัก: Module 3: Proxying (Forward, Web, HTTPS Tunneling with Root CA), Record & Replay, and Interactive Breakpoints

❓ หมุดตั้งโจทย์: "ทำไมบทนี้ถึงชื่อนี้? และเรากำลังเรียนเรื่องนี้ไปเพื่ออะไร?"

ตอบ: ในชีวิตการทำงานจริง เราต้องทำงานร่วมกับระบบภายนอก (Third-party APIs) หรือ Legacy Systems ที่ไม่มีเอกสาร API (API Spec) หรือเอกสารเก่าไม่อัปเดต การนั่งเดา Payload หรือพิมพ์ JSON Mocks ด้วยมือทีละข้อจะเสียเวลาและเสี่ยงต่อความผิดพลาด บทนี้ตั้งชื่อว่า Proxying, Record & Replay, and Interactive Breakpoints เพราะ MockServer สามารถทำหน้าที่เป็น Proxy (คั่นกลางบนสายเคเบิล) เพื่อแอบส่องและบันทึกทราฟฟิกจริง (Record) นำมาแปลงเป็น Mocks อัตโนมัติ (Replay) และยังเปิดโอกาสให้ดักแก้ไขทราฟฟิกกลางอากาศ (Interactive Breakpoints) ช่วยให้แกะรอยและสร้าง Mocks จากระบบจริงได้อย่างแม่นยำ 100% โดยไม่ต้องเดา

PROGRESS ROADMAP:
✓ Day 1: Mod 1
✓ Day 2: Mod 2
▶ Day 3: Mod 3
Day 4: Mod 4
Day 5: Mod 5
Day 6: Mod 6

[2] ส่วนที่ 2: เรื่องราวและมโนทัศน์เชิงลึก (Narrative, Case Study & Mental Models)

1. ฉากสถานการณ์จริง (The Narrative/Case Study)

การเชื่อมต่อ Legacy Payment Gateway อายุ 15 ปี ที่ไม่มี API Documentation

บริษัทสตาร์ทอัปแห่งหนึ่งต้องเชื่อมต่อระบบชำระเงินเข้ากับธนาคารท้องถิ่นรายหนึ่ง ซึ่งใช้ระบบโบราณ เอกสาร API ที่ธนาคารให้มาเป็นไฟล์ PDF ที่อัปเดตครั้งสุดท้ายเมื่อปี 2010 เมื่อทีมวิศวกรพยายามเขียน Mocks ตามเอกสาร PDF ผลคือยิงทดสอบไม่เคยผ่าน เพราะเซิร์ฟเวอร์จริงของธนาคารมีการส่ง Custom Headers และลับโครงสร้าง JSON ไม่ตรงกับเอกสาร

ทีมงานไม่สามารถนั่งเดาโครงสร้าง Request/Response ได้อีกต่อไป และสภาพแวดล้อม Sandbox ของธนาคารก็อนุญาตให้ยิงทดสอบได้เฉพาะช่วงเวลา 01:00 - 03:00 น. เท่านั้น

💡 การนำ Proxying & Record/Replay เข้ามาแก้ปัญหา: ทีมงานเปิด MockServer ทำหน้าที่เป็น HTTPS Tunneling Proxy คั่นกลางระหว่างแอปพลิเคชันทดสอบกับ Sandbox ของธนาคาร ในช่วงเวลา 01:00 น. ทีมงานสั่งรัน Test Flow เพียงครั้งเดียว ให้ทราฟฟิกวิ่งผ่าน MockServer Proxy ซึ่งทำการสกัดรหัส SSL ผ่าน Dynamic Root CA Certificate และเก็บบันทึกทราฟฟิกทั้งหมดไว้ (Record) จากนั้นสั่งให้ MockServer แปลงบันทึกทราฟฟิกนั้นให้กลายเป็น Expectation JSON อัตโนมัติ (Replay) รัน Integration Test ได้ตลอด 24 ชั่วโมง โดยไม่ต้องง้อ Sandbox ของธนาคารอีกเลย!

2. ถอดรหัสศัพท์เทคนิคและอุปมาอุปไมย (Explicit Terms & Mental Models)
01. Forward & Web Proxying
ด่านตรวจจราจรคั่นกลาง

แปลตรงตัว: การตั้งเซิร์ฟเวอร์คั่นกลางเพื่อส่งผ่านและส่องดูข้อมูล

อุปมาอุปไมย: เหมือน "ด่านตรวจทางด่วน" ที่รถทุกคันต้องวิ่งผ่าน เจ้าหน้าที่ด่านตรวจสามารถมองเห็นป้ายทะเบียน และของที่บรรทุกอยู่ในรถ (Headers & Payload) ก่อนปล่อยให้รถวิ่งต่อไปยังปลายทาง

02. HTTPS Tunneling with Dynamic Root CA
ตู้คอนเทนเนอร์กระจกใสถอดรหัส SSL

แปลตรงตัว: การอุโมงค์เชื่อมต่อแบบปลอดภัยโดยใช้ใบรับรอง Root CA ไดนามิก

อุปมาอุปไมย: เหมือน "ตู้ขนส่งความปลอดภัยสูงที่ใช้กระจกใสพิเศษ" ปกติการส่งข้อมูล HTTPS จะเหมือนรถขนเงินที่ปิดมิดชิดมองไม่เห็นข้างใน แต่ MockServer จะใช้ใบรับรอง Root CA พิเศษเปรียบเหมือนแว่นตาเอกซเรย์ ทำให้สามารถมองเห็นเนื้อหาข้อมูลภายในอุโมงค์ HTTPS ได้

03. Record & Replay Workflow
ม้วนเทปอัดเสียงแล้วนำมาเปิดซ้ำ

แปลตรงตัว: การบันทึกทราฟฟิกแล้วนำกลับมาจำลองซ้ำ

อุปมาอุปไมย: เหมือน "การกดอัดเทปเสียงร้องเพลง" เมื่อยิง Request จริงผ่าน Proxy ครั้งแรก ม้วนเทปจะอัดเสียงไว้ (Record) หลังจากนั้นกดปุ่มเล่นเทป (Replay) เสียงเพลงเดิมก็จะเล่นออกมาทันที

04. Interactive Breakpoints
ด่านกักรถเพื่อดัดแปลงของในท้ายรถ

แปลตรงตัว: จุดหยุดพักเพื่อแก้ไขข้อมูลสดกลางอากาศ

อุปมาอุปไมย: เหมือน "ด่านศุลกากรที่สั่งกักรถชั่วคราว" เมื่อ Request วิ่งเข้ามา ด่านจะกักรถไว้แล้วเปิดโอกาสให้เราเข้าไปแก้ไขสิ่งของในท้ายรถ (ปรับแก้ JSON Body หรือ Status Code สดๆ) ก่อนปล่อยให้รถวิ่งต่อไปยังจุดหมาย

⚠️ Root Cause (รากของปัญหา)

การเสียเวลาพัฒนาซอฟต์แวร์ไปกับการ Guessing API Contracts (เดาสเปก API เอง) เนื่องจากเอกสารไม่อัปเดต หรือไม่มี Sandbox ให้ใช้ตลอดเวลา

📉 Business Impact (ผลกระทบทางธุรกิจ)

ชิ้นงานเสร็จล่าช้ากว่ากำหนด (Project Delay), เกิด Bug บน Production จากการที่ Mocks ไม่ตรงกับพฤติกรรมจริงของ Third-party และเสียค่าใช้จ่ายในการเข้าใช้ Sandbox

[3] ส่วนที่ 3: การถอดรหัสและอธิบายโค้ดอย่างละเอียด (Line-by-line Breakdown)

1. ดึงบันทึก Expectations จาก Proxy (PUT /mockserver/retrieve)
# [Line 1] ส่งคำสั่ง PUT ไปยัง Endpoint /mockserver/retrieve พร้อมระบุ query parameter type=EXPECTATIONS
curl -X PUT "http://localhost:1080/mockserver/retrieve?type=EXPECTATIONS"

# โครงสร้าง JSON ผลลัพธ์ที่ MockServer สกัดออกมาให้อัตโนมัติ:
[
  {
    "httpRequest": {
      "method": "POST",
      "path": "/api/v1/payments",
      "headers": { "Host": ["api.bank.com"], "Content-Type": ["application/json"] },
      "body": "{\"amount\": 500, \"currency\": \"THB\"}"
    },
    "httpResponse": {
      "statusCode": 200,
      "headers": { "Content-Type": ["application/json"] },
      "body": "{\"status\": \"SUCCESS\", \"transactionId\": \"TX-998811\"}"
    }
  }
]
2. การตั้งค่า Port Forwarding Action (httpForward)
{
  "httpRequest": {                         // [Section 1] ดักจับ Request ที่ยิงเข้ามาหา Path /forward-test
    "method": "POST",
    "path": "/forward-test"
  },
  "httpForward": {                         // [Section 2] สั่งให้ MockServer ทำหน้าที่เป็น Reverse Proxy ส่งต่อ
    "host": "httpbin.org",                 // ระบุ Host ปลายทางที่จะส่งต่อ Request ไป
    "port": 80,                            // ระบุพอร์ตปลายทาง (80 สำหรับ HTTP, 443 สำหรับ HTTPS)
    "scheme": "HTTP"                       // ระบุโปรโตคอล (HTTP หรือ HTTPS)
  }
}
3. การทำ Sequence Verification (PUT /mockserver/verifySequence)
{
  "httpRequests": [                        // [Section 1] กำหนดอาร์เรย์ของ Request ที่ต้องเกิดขึ้นเรียงตามลำดับ
    {
      "method": "POST",
      "path": "/api/v3/init"               // ขั้นตอนที่ 1: ต้องยิง /init ก่อน
    },
    {
      "method": "POST",
      "path": "/api/v3/process"            // ขั้นตอนที่ 2: ต้องยิง /process ตามมาติดๆ
    }
  ]
}

[4] ส่วนที่ 4: คู่มือการใช้งานผ่าน Web UI / Dashboard

เปิดเว็บเบราว์เซอร์ไปที่: http://localhost:1080/mockserver/dashboard

========================================================================================
                          MOCKSERVER WEB DASHBOARD (PORT 1080)
========================================================================================
 [ Active Expectations ] | [ Recorded Requests / Logs ] | [ Breakpoints ] | [ Reset All ]
----------------------------------------------------------------------------------------
Recorded Requests / Logs: - ทุกรายการ Request ที่วิ่งผ่าน Proxy จะมาปรากฏที่นี่
                         - สามารถคลิกดู Headers และ Body ของแต่ละ Request/Response ได้

"Create Expectation" Button: - ปุ่มลัดในแท็บ Logs ข้างๆ ทุก Request
                             - สกัดทราฟฟิกจริงไปสร้างเป็น Active Expectation ทันทีโดยไม่ต้องเขียน JSON เอง

Interactive Breakpoints: - ไปที่เมนู Breakpoints แล้วเปิดใช้งาน (Enable Breakpoint)
                         - กักทราฟฟิก In-flight ไว้ แล้วแก้ไข Payload สดๆ บนหน้าเว็บก่อนปล่อยผ่าน

[5] ส่วนที่ 5: โครงสร้างไฟล์โปรเจกต์มาตรฐาน (Enterprise File Structure Best Practice)

mockserver-module3-enterprise/
├── docker-compose.yml
├── config/
│   ├── mockserver.properties
│   └── certs/
│       └── MockServerPKCS12.p12            # ใบรับรอง Root CA สำหรับทำ HTTPS Proxying
├── expectations/
│   ├── recorded/
│   │   └── bank-api-recorded.json          # ไฟล์ Mocks ที่สกัดจาก Record/Replay
│   └── forwarding/
│       └── reverse-proxy-rules.json        # Rules การทำ Port Forwarding
├── scripts/
│   ├── record_traffic.sh                   # สคริปต์สั่งยิงผ่าน Proxy แล้วสกัด Expectations
│   └── reset_mockserver.sh
└── tests/
    └── ProxyAndVerificationTest.java

[6] ส่วนที่ 6: แบบฝึกหัดภาคปฏิบัติแน่นๆ (Hands-on Refactoring & 6 Drills)

❌ Flawed Approach (นั่งเขียน Mocks โดยการเดาสเปกเอง)

นั่งพิมพ์ JSON เองตามเอกสาร PDF เก่าที่ไม่ตรงกับระบบจริง:

{
  "httpRequest": { "method": "POST", "path": "/payment" },
  "httpResponse": { "body": "{\"status\": \"OK\"}" } // เซิร์ฟเวอร์จริงใช้ "SUCCESS" ไม่ใช่ "OK" -> พังบน Prod!
}
✅ Refactored Approach (สกัด Mocks จากการ Record ทราฟฟิกจริง)

ยิงผ่าน Proxy 1 ครั้งแล้วสกัดสเปกจริงออกมา Replay ได้ตรง 100%:

curl -x http://localhost:1080 http://api.bank.com/payment -d '{"amount":100}'
curl -X PUT "http://localhost:1080/mockserver/retrieve?type=EXPECTATIONS" > expectations/recorded.json
ชุดแบบฝึกหัดปฏิบัติการ 6 ข้อ (Hands-on Drill Pack)

ก่อนเริ่มทำ ตรวจสอบว่าเปิด MockServer ไว้ที่ http://localhost:1080 เรียบร้อยแล้ว

Drill 3.1: Forward Proxying & Recording Traffic (สั่งส่องและบันทึกทราฟฟิกจริง)

Setup & Action:

curl -v -x http://localhost:1080 "http://httpbin.org/get?userId=U999&role=admin"

Retrieve: curl -X PUT "http://localhost:1080/mockserver/retrieve?type=EXPECTATIONS" (ได้สเปก JSON Expectation ฉบับเต็มที่สกัดจาก Request/Response จริง)

Drill 3.2: Replaying Recorded Expectations (นำม้วนเทปกลับมาทำ Mocks)

Setup:

curl -X PUT "http://localhost:1080/mockserver/expectation" -H "Content-Type: application/json" -d '{"httpRequest": { "method": "GET", "path": "/get", "queryStringParameters": { "userId": ["U999"] } }, "httpResponse": { "statusCode": 200, "headers": { "Content-Type": ["application/json"] }, "body": "{\"source\": \"Replayed Mock\"}" }}'

Test: curl -i "http://localhost:1080/get?userId=U999" (ได้ HTTP 200 OK พร้อม Body {"source": "Replayed Mock"})

Drill 3.3: Strict Verification with Exact Count (ตรวจนับจำนวนการยิงเป๊ะๆ)

Action: ยิง Request 2 ครั้ง:

curl -X POST http://localhost:1080/api/v3/telemetry -d '{"event": "click_1"}'
curl -X POST http://localhost:1080/api/v3/telemetry -d '{"event": "click_2"}'

Verify: curl -X PUT "http://localhost:1080/mockserver/verify" -H "Content-Type: application/json" -d '{"httpRequest": { "method": "POST", "path": "/api/v3/telemetry" }, "times": { "exact": 2 }}' (ได้ HTTP 202 Accepted)

Drill 3.4: Sequence Verification (ตรวจสอบลำดับขั้นตอนการยิง)

Action: ยิงตามลำดับ:

curl -X POST http://localhost:1080/api/v3/init
curl -X POST http://localhost:1080/api/v3/process

Verify Sequence: curl -X PUT "http://localhost:1080/mockserver/verifySequence" -H "Content-Type: application/json" -d '{"httpRequests": [{"method": "POST", "path": "/api/v3/init"}, {"method": "POST", "path": "/api/v3/process"}]}' (ได้ HTTP 202 Accepted)

Drill 3.5: Port Forwarding Action (httpForward)

Setup:

curl -X PUT "http://localhost:1080/mockserver/expectation" -H "Content-Type: application/json" -d '{"httpRequest": { "method": "POST", "path": "/forward-test" }, "httpForward": { "host": "httpbin.org", "port": 80, "scheme": "HTTP" }}'

Test: curl -i -X POST http://localhost:1080/forward-test -d '{"data": "forwarded"}' (ได้รับ Response จาก httpbin.org)

Drill 3.6: Reset & Clear Logs (การล้างกระดานและเตรียมความพร้อม)

Action:

curl -X PUT "http://localhost:1080/mockserver/reset"

Test Verification: curl -X PUT "http://localhost:1080/mockserver/retrieve?type=EXPECTATIONS" (ได้อาร์เรย์ว่างเปล่า [])

⚡ Instant Feedback Quiz

ส่วนที่ 7: แบบทดสอบประเมินความรู้ Day 3 / Module 3 (10 ข้อ)

คลิกเลือกคำตอบข้อที่ถูกต้อง ระบบจะตรวจให้คะแนนและแสดงผลเฉลยพร้อมคำอธิบายทันที!

คะแนนสด 0 / 10
[8]

ส่วนที่ 8: สรุปหมุดเชื่อมโยงกลับหาหัวข้อบท (Closing Title Connection Wrap-up)

เนื้อหาและแบบฝึกหัดทั้งหมดในวันนี้ ตอบและสะท้อนชื่อบท Day 3 / Module 3: Proxying, Record & Replay, and Interactive Breakpoints อย่างสมบูรณ์: การใช้ Proxying (Forward / HTTPS Tunneling) ช่วยให้เราเชื่อมต่อและบันทึกทราฟฟิกจริงจาก Third-party APIs ได้อย่างแม่นยำ, การใช้ Record & Replay Workflow ช่วยเปลี่ยนม้วนเทปบันทึกทราฟฟิกเป็น Mocks ที่เสถียรรวดเร็ว และการใช้ Interactive Breakpoints ก็ช่วยให้เราทดสอบดักแก้ไขข้อมูลสดกลางอากาศได้เหมือนมีกล้องตรวจจับและศุลกากรส่วนตัวนั่นเองครับ!