API gateway vs BFF สำหรับไคลเอนต์เว็บและมือถือ: ข้อแลกเปลี่ยน
API gateway vs BFF: เรียนรู้ว่าทั้งสองแบบส่งผลต่อการเวอร์ชัน ประสิทธิภาพ และการแยกเอนด์พอยต์สาธารณะกับภายในอย่างไรสำหรับเว็บและแอปมือถือ

ปัญหา: แบ็กเอนด์เดียว หลายไคลเอนต์ ความต้องการที่เปลี่ยนไป
จุดเริ่มต้นที่พบได้บ่อยคือเรียบง่าย: แบ็กเอนด์หนึ่งตัวเปิดเผยชุดเอนด์พอยต์ แล้วทั้งเว็บแอปและแอปมือถือเรียกใช้มัน รู้สึกว่ามีประสิทธิภาพเพราะมีที่เดียวในการเพิ่มฟีเจอร์ แก้บั๊ก และบังคับใช้กฎ
แต่ความเป็นจริงมาถึงเร็ว ๆ หน้าจอเว็บมักจะต้องการข้อมูลหนา ๆ ตัวกรอง การส่งออก และการกระทำของแอดมิน ในขณะที่มือถือมักต้องการฟิลด์น้อยลง หน้าจอที่เร็วขึ้น โฟลว์ที่รองรับออฟไลน์ และระมัดระวังเรื่องแบตเตอรี่และการใช้ข้อมูล แม้ฟีเจอร์จะดูเป็น "เดียวกัน" รูปร่างของ API ที่ดีที่สุดสำหรับแต่ละไคลเอนต์ก็ไม่ค่อยเหมือนกัน
เมื่อเวลาผ่านไป เอนด์พอยต์จะเบนออกไป ทีมเว็บเพิ่มฟิลด์เพื่อมุมมองตารางใหม่ มือถือขอให้เอาพayload หนักออกและรวมการเรียกหลายครั้งเป็นหนึ่งคนเพิ่มพารามิเตอร์ "แค่สำหรับ iOS" คนอีกคนใช้เอนด์พอยต์แอดมินภายในในแอปสาธารณะเพราะมัน "มีแล้ว" สิ่งที่เริ่มจาก API สะอาดกลายเป็นชุดของข้อยอมความ
ความเสี่ยงจะปรากฏอย่างรวดเร็ว:
- การแตกเมื่อไคลเอนต์หนึ่งปล่อยเร็วกว่าคนอื่น
- แอปช้าลงจากเพย์โหลดขนาดใหญ่หรือหลายรอบเรียก
- โค้ดแบ็กเอนด์ซับซ้อนขึ้นเมื่อทุกเอนด์พอยต์พยายามรองรับทุกไคลเอนต์
- การเปิดเผยข้อมูลโดยไม่ตั้งใจเมื่อฟิลด์หรือการกระทำภายในหลุดเข้ามาใน API สาธารณะ
- การเวอร์ชันที่เจ็บปวดเพราะ "การเปลี่ยนแปลงเล็กน้อย" ไม่เล็กสำหรับไคลเอนต์เก่า
นี่คือความตึงเครียดหลักเบื้องหลังการถกเถียงเรื่อง API gateway vs BFF คุณต้องการ API สาธารณะที่เสถียรให้มือถือและเว็บพึ่งพาได้ พร้อมกับให้แต่ละไคลเอนต์มีพื้นที่พัฒนาไปตามจังหวะของตัวเอง
API gateway และ BFF: คืออะไร (และไม่ใช่)
API gateway คือประตูหน้าของ API ของคุณ ไคลเอนต์เรียกเกตเวย์ แล้วเกตเวย์จะกำหนดเส้นทางคำขอไปยังเซอร์วิสที่ถูกต้อง มักจัดการเรื่องที่ใช้ร่วมกันที่ไม่ต้องการทำซ้ำหลายที่ เช่น การตรวจสอบตัวตน ขีดจำกัดอัตรา การบันทึกคำขอ และการปรับรูปร่างคำขอพื้นฐาน
BFF (backend-for-frontend) คือแบ็กเอนด์เล็ก ๆ ที่สร้างมาสำหรับไคลเอนต์เฉพาะ หรือกลุ่มไคลเอนต์ เช่น "เว็บ" และ "มือถือ" ไคลเอนต์เรียก BFF ของตัวเอง แล้ว BFF จะเรียกเซอร์วิสเบื้องหลัง แนวคิดสำคัญคือความมุ่งเน้น: BFF พูดภาษาของไคลเอนต์ได้ (หน้าจอ โฟลว์ เพย์โหลด) แม้ว่าบริการหลักจะยังคงเป็นแบบทั่วไป
สิ่งที่ทั้งสองรูปแบบไม่ใช่: พวกมันไม่ใช่ตัวแทนของเซอร์วิสโดเมนที่ดีหรือโมเดลข้อมูลที่สะอาด บริการแกนหลัก ฐานข้อมูล และกฎธุรกิจของคุณยังคงเป็นแหล่งความจริง เกตเวย์หรือ BFF ไม่ควรกลายเป็นกลุ่มก้อนของตรรกะธุรกิจที่ค่อย ๆ กลายเป็นแบ็กเอนด์หลักของคุณ
วิธีง่าย ๆ ในการแยกความต่าง:
- Gateway: จุดเข้าเดียว ข้อกังวลร่วม การกำหนดเส้นทางและการปกป้อง
- BFF: API เฉพาะไคลเอนต์ที่ลดงานฝั่งไคลเอนต์และซ่อนความซับซ้อนภายใน
คุณสามารถรวมทั้งสองได้เช่นกัน การตั้งค่าที่พบทั่วไปคือเกตเวย์เป็นขอบสาธารณะ แล้วมี BFF แยกตามเว็บและมือถืออยู่เบื้องหลัง เกตเวย์จัดการความปลอดภัยชั้นนอกและกฎทราฟฟิก ขณะที่แต่ละ BFF ปรับรูปร่างเอนด์พอยต์และการตอบกลับให้ตรงกับไคลเอนต์
เส้นทางคำขอเปลี่ยนไปอย่างไรในแต่ละรูปแบบ
ความแตกต่างที่ใหญ่ที่สุดระหว่าง API gateway และ BFF คือคุณวางตรรกะ "ประตูหน้า" ไว้ที่ไหน: การกำหนดเส้นทาง การตรวจสอบตัวตน และการปรับรูปร่างการตอบกลับ
กับ API gateway ไคลเอนต์มักคุยกับจุดเข้าเดียวที่ใช้ร่วม เกตเวย์ส่งต่อคำขอไปยังเซอร์วิสภายใน มักทำงานพื้นฐานเช่นการตรวจโทเคน การจำกัดอัตรา และการกำหนดเส้นทางตามพาธ
กับ BFF แต่ละประเภทไคลเอนต์ (เว็บ, iOS, Android) เรียกแบ็กเอนด์ที่สร้างมาสำหรับมันโดยเฉพาะ BFF นั้นเรียกเซอร์วิสภายในและส่งกลับการตอบสนองที่ปรับแต่งสำหรับหน้าจอและข้อจำกัดของไคลเอนต์
ภาพง่าย ๆ ของเส้นทางคำขอ:
- เส้นทางแบบ API gateway: Client -> Gateway -> Service(s) -> Response
- เส้นทางแบบ BFF: Client -> BFF (web or mobile) -> Service(s) -> Response
ความเป็นเจ้าของมักเปลี่ยนด้วย ทีมแพลตฟอร์มหรือโครงสร้างพื้นฐานมักเป็นเจ้าของเกตเวย์เพราะกระทบทุกทีมและทุกเซอร์วิส ทีมฟีเจอร์มักเป็นเจ้าของ BFF เพราะมันขยับตาม UI และรอบการปล่อยของมัน
การตรวจสอบตัวตนมักไหลแบบนี้: ไคลเอนต์ส่งโทเคน ขอบระบบ (เกตเวย์หรือ BFF) ตรวจสอบมันหรือส่งต่อไปยังเซอร์วิส auth แล้วส่งรายละเอียดตัวตน (user id, roles) ไปยังเซอร์วิสด้านล่าง ความต่างคือคุณใช้กฎเฉพาะไคลเอนต์ที่ไหน กับเกตเวย์นโยบายมักเป็นแบบทั่วไปและสอดคล้องกัน ขณะที่ BFF สามารถเพิ่มการปรับรูปร่างเฉพาะไคลเอนต์ได้ เช่น ส่งเพย์โหลดเล็กลงสำหรับมือถือหรือรวมการเรียกหลายเซอร์วิสเป็นหนึ่งรายการสำหรับเครือข่ายช้า
การปรับรูปร่างตรงนี้คือข้อได้เปรียบของ BFF แต่ก็หมายถึงชิ้นส่วนที่ต้องดีพลอยและดูแลมากขึ้น
การแยกเอนด์พอยต์สาธารณะและภายในอย่างปลอดภัย
เอนด์พอยต์สาธารณะคือเส้นทาง API ที่เว็บแอป แอปมือถือ พาร์ทเนอร์ หรือบุคคลที่สามสามารถเข้าถึง ให้ถือว่ามันเป็นพื้นที่เป็นศัตรูก่อน โดยปริยาย เพราะคุณควบคุมเครือข่ายที่มันเดินทางผ่านหรือโค้ดไคลเอนต์ที่เรียกมันไม่ได้
เอนด์พอยต์ภายในคือสำหรับทราฟฟิกระหว่างเซอร์วิสภายในระบบของคุณ มันสามารถเปลี่ยนเร็วกว่า สมมติบริบทได้มากกว่า และเปิดเผยข้อมูลที่ละเอียดขึ้นได้ แต่ไม่ควรเข้าถึงได้โดยตรงจากอินเทอร์เน็ตสาธารณะ
กับ API gateway การแยกมักเป็นเชิงกายภาพและเข้าใจง่าย: มีเพียงเกตเวย์ที่ถูกเปิดเผย และมันตัดสินใจว่าเส้นทางภายนอกใดมีอยู่ ทุกอย่างหลังมันยังเป็นส่วนตัว คุณสามารถเก็บ API บริการภายในให้อธิบายชัดเจน ในขณะที่เกตเวย์บังคับพื้นผิวที่ปลอดภัยและเล็กกว่า
กับ BFF การแยกเป็นเรื่องของขอบเขตผลิตภัณฑ์ ไคลเอนต์แต่ละประเภทคุยกับ BFF ของตัวเอง และ BFF เรียกเซอร์วิสภายใน นั่นทำให้คุณซ่อนความซับซ้อนภายใน: BFF อาจเรียกสามเซอร์วิส ผสานผลลัพธ์ แล้วเปิดเอนด์พอยต์เดียวที่ง่ายและตรงตามสิ่งที่ไคลเอนต์ต้องการ
การแยกจะปลอดภัยได้ก็ต่อเมื่อคุณเพิ่มการควบคุมปฏิบัติจริง:
- การอนุญาตเฉพาะเจาะจง: บทบาทและสโคปต่อเส้นทาง ไม่ใช่สวิตช์ "ล็อกอินแล้ว" เดียว
- ขีดจำกัดอัตราต่อผู้ใช้ โทเคน และ IP สำหรับเอนด์พอยต์สาธารณะ
- การกรองเพย์โหลด: ส่งกลับแค่สิ่งที่ไคลเอนต์ต้องการ ตัด ID ภายใน ข้อมูลดีบั๊ก และฟิลด์สำหรับแอดมิน
- รายการอนุญาตชัดเจน: เอนด์พอยต์ใดเป็นสาธารณะ หรือสำหรับภายในเท่านั้น
ตัวอย่าง: แอปมือถือต้องการหน้าจอ "คำสั่งซื้อของฉัน" BFF สามารถเปิด /orders โดยมีแค่สถานะคำสั่งซื้อและยอดรวม ขณะที่เซอร์วิสคำสั่งซื้อภายในเก็บรายละเอียดการแบ่งต้นทุนและธงป้องกันการฉ้อโกงไว้เป็นส่วนตัว
การเวอร์ชัน: อะไรที่ง่ายขึ้นและอะไรที่ยากขึ้น
ความเจ็บปวดเรื่องการเวอร์ชันมักเกิดเมื่อเว็บและมือถือเดินหน้าไม่พร้อมกัน ทีมเว็บอาจปล่อยและย้อนกลับได้ในไม่กี่ชั่วโมง ขณะที่แอปมือถืออาจใช้วันหรือสัปดาห์เพราะการทบทวนในสโตร์และผู้ใช้ที่ไม่อัพเดต ช่องว่างนี้คือที่การตัดสินใจใช้ API gateway vs BFF มีความเป็นประโยชน์เชิงปฏิบัติ
กับ API gateway คุณสามารถวางการเวอร์ชันที่ประตูหน้าเดียว (เช่น /v1/..., /v2/...) ซึ่งอธิบายง่ายและกำหนดเส้นทางได้สะดวก ข้อเสียคือเกตเวย์อาจกลายเป็นพิพิธภัณฑ์เวอร์ชันถ้าไคลเอนต์และการผสานจากพาร์ทเนอร์หลายคนยังยึดติดกับเวอร์ชันเก่า คุณจะต้องรองรับรูปแบบเดิมของข้อมูลนานขึ้น
กับ BFF การเวอร์ชันมักเป็น "ต่อไคลเอนต์" BFF ของมือถืออาจคงสัญญาเดิมไว้ ขณะที่ BFF เว็บขยับได้เร็วขึ้น ซึ่งมักลดแรงกดดันที่จะต้องเก็บเวอร์ชันสาธารณะไว้ตลอดไป ข้อแลกเปลี่ยนคือชิ้นส่วนที่เคลื่อนไหวมากขึ้น: คุณมีการตัดสินใจเวอร์ชันและดีพลอยหลายชิ้นให้จัดการ
การเวอร์ชันในบริการภายในก็ทำได้ แต่มันผลักการเปลี่ยนที่มาจากไคลเอนต์ลึกเข้าไปในระบบของคุณ และอาจทำให้โค้ดภายในอ่านยากขึ้นเพราะตรรกะต้องแยกตามเวอร์ชันไคลเอนต์
การเปลี่ยนแปลงที่ไม่ทำลายคือเพื่อนที่ดีที่สุด: เพิ่มฟิลด์ทางเลือก เพิ่มเอนด์พอยต์ใหม่ หรือรับฟิลด์อินพุตเพิ่มเติม การเปลี่ยนที่ทำลายได้แก่ การเปลี่ยนชื่อฟิลด์ การเปลี่ยนชนิดข้อมูล (เช่น string -> number) หรือการลบเอนด์พอยต์
การยกเลิกใช้งานทำได้ดีที่สุดเมื่อวางแผนไว้:
- กำหนดวันซันเซ็ตที่ชัดเจนและสื่อสารล่วงหน้า
- ติดตามการใช้งานของเวอร์ชันเก่า (ล็อก เมตริก) และดูหา "คนค้าง"
- ปล่อยอัพเดตฝั่งไคลเอนต์ก่อน (โดยเฉพาะมือถือ) แล้วค่อยลบเส้นทางเก่า
- คืนข้อผิดพลาดที่ชัดเจนเมื่อเวอร์ชันเก่าถูกบล็อกในที่สุด
ประสิทธิภาพ: latency ขนาดเพย์โหลด และจำนวนการเรียก
ประสิทธิภาพในสถาปัตยกรรม API gateway vs BFF เป็นการแลกเปลี่ยน: เพิ่มฮอปภายในระบบอีกหนึ่งแต้ม เทียบกับลดฮอปบนเครือข่ายของไคลเอนต์ ตัวเลือกที่เร็วที่สุดมักเป็นตัวเลือกที่ลดเวลาบนเครือข่ายไคลเอนต์แม้จะเพิ่มขั้นตอนเล็ก ๆ บนเซิร์ฟเวอร์
BFF มักชนะเมื่อไคลเอนต์จะต้องทำหลายการเรียก แทนที่เว็บและมือถือจะเรียกห้าเอนด์พอยต์แล้วต่อตัวบนอุปกรณ์ BFF สามารถดึงข้อมูลที่ต้องการจากเซิร์ฟเวอร์แล้วคืนหนึ่งการตอบกลับ การทำเช่นนี้มักลดความหน่วงรวมบนมือถือเพราะเครือข่ายเซลลูลาร์เพิ่มความล่าช้าต่อคำขอ
ข้อดีด้านประสิทธิภาพที่พบบ่อยจากเกตเวย์หรือ BFF:
- การรวมข้อมูล: รวมจากหลายเซอร์วิสเป็นการตอบกลับเดียว
- แคชที่ชาญฉลาด: แคชที่ขอบหรือที่ BFF สำหรับหน้าจอที่อ่านหนัก
- เพย์โหลดเล็กลง: ส่งเฉพาะฟิลด์ที่หน้าจอต้องการ
- ลดรอบเรียก: ลดพฤติกรรมที่แชทตี้ของไคลเอนต์
- การบีบอัดและ timeout ที่สอดคล้อง: กำหนดค่าเริ่มต้นในที่เดียว
แต่รูปแบบนี้ก็ทำให้แย่ได้เช่นกัน ชั้นเพิ่มแต่ละชั้นเพิ่มงาน CPU และสถานที่ให้รอ หากคุณทำตรรกะการรวมซ้ำสำหรับเว็บและมือถือ คุณอาจทำงานซ้ำและสร้างพฤติกรรมไม่สอดคล้องกัน การดึงข้อมูลเกินจำเป็นก็เป็นการสูญเสียอีกอย่าง: เอนด์พอยต์ทั่วไปที่พยายามตอบทุกหน้าจออาจส่งเพย์โหลดใหญ่เสียเวลาและแบนด์วิดท์
ความเป็นจริงของมือถือทำให้การแลกเปลี่ยนชัดเจนขึ้น เครือข่ายกระเด้งทำให้การ retry และ timeout เป็นปกติ แต่ละคำขอเพิ่มการใช้แบตเตอรี่ การเริ่มเครื่องเย็น (cold starts) ก็สำคัญ: ถ้าแอปต้องการหลายคำขอก่อนหน้าจอแรกจะใช้งานได้ ผู้ใช้จะรู้สึกถึงมัน
กฎปฏิบัติ: ปรับให้จำนวนคำขอของไคลเอนต์น้อยลงก่อน แล้วค่อยปรับฮอปที่เพิ่มขึ้น
วิธีด่วนในการตัดสินแบบดีไซน์
ถ้าหน้าจอต้องการการเรียงลำดับมากกว่า 2–3 ครั้ง ให้พิจารณาการรวมข้อมูล ถ้าการตอบกลับใหญ่และส่วนมากไม่ได้ใช้ ให้พิจารณาแยกเอนด์พอยต์หรือใช้ BFF ตามไคลเอนต์
การปฏิบัติการ: การปล่อย โมนิเตอร์ และการสเกล
คำถามเชิงปฏิบัติการที่ใหญ่คือคุณยินดีจะรันและดูแลชิ้นส่วนเคลื่อนไหวกี่ชิ้น เกตเวย์มักกลายเป็นโครงสร้างพื้นฐานที่ใช้ร่วมกันสำหรับหลายทีมและไคลเอนต์ BFF มักเป็นเซอร์วิสขนาดเล็ก แต่คุณอาจมีหนึ่งตัวต่อไคลเอนต์ (เว็บ, iOS, Android, พาร์ทเนอร์) ทำให้ภาระการปล่อยและ on-call เพิ่มขึ้น
ในการทดสอบและปล่อย เกตเวย์อาจปลอดภัยกว่าเมื่อคุณต้องการแค่การกำหนดเส้นทาง auth และขีดจำกัดการเรียก การเปลี่ยนแปลงรวมศูนย์ ดังนั้นความผิดพลาดเดียวอาจกระทบทุกคน BFF ลด blast radius เพราะการเปลี่ยนแปลงเฉพาะเว็บจะดีพลอยไปที่เว็บ BFF ไม่ใช่มือถือ ข้อแลกคือมี pipeline เพิ่มขึ้นให้ดูแลและเวอร์ชันที่มากขึ้นในระหว่างการทำงาน
สำหรับการสังเกตการณ์ คุณต้องเห็นคำขอผู้ใช้หนึ่งรายการผ่านทุกเลเยอร์ โดยเฉพาะเมื่อคำขอมือถือหนึ่งครั้งกระตุ้นหลายการเรียกแบ็กเอนด์
- ใช้ correlation ID และส่งผ่านเกตเวย์ BFF และล็อกแบ็กเอนด์
- เก็บ traces เพื่อระบุว่าส่วนไหนใช้เวลา (เกตเวย์, BFF, เซอร์วิสด้านล่าง)
- เก็บล็อกแบบมีโครงสร้าง (ไคลเอนต์, เอนด์พอยต์, รหัสสถานะ, latency, ขนาดเพย์โหลด)
- ติดตามเมตริกสำคัญต่อเอนด์พอยต์: อัตราข้อผิดพลาด p95 latency ปริมาณ
การสเกลก็ดูต่างกัน เกตเวย์คือจุดคอขวดร่วม: ต้องรับมือสไปก์และเอนด์พอยต์ฮอตโดยไม่เป็นคอขวด BFF ให้คุณสเกลต่อไคลเอนต์ ซึ่งช่วยเมื่อทราฟฟิกเว็บพุ่งในช่วงเวลาทำการขณะที่มือถือคงที่
ในกรณีเหตุขัดข้อง ความผิดพลาดอาจ "ย้าย" ขึ้นอยู่กับรูปแบบ กับเกตเวย์ปัญหามักปรากฏเป็น 5xx ขนาดใหญ่หรือความล้มเหลวของ auth ขณะที่กับ BFF ปัญหาอาจจำกัดอยู่ที่ฟีเจอร์ของไคลเอนต์หนึ่ง ทำให้ runbook ชัดเจนว่าควรมองหาที่ไหนก่อน และเก็บพฤติกรรม fallback ง่าย (เช่น คืนการตอบแบบลดทอนแทนที่จะ timeout)
วิธีเลือก: กระบวนการตัดสินใจทีละขั้นตอนง่าย ๆ
การเลือกระหว่าง API gateway และ BFF เป็นเรื่องของความต้องการไคลเอนต์ในแต่ละวันมากกว่าทฤษฎี
กระบวนการตัดสินใจเชิงปฏิบัติ
-
เริ่มจากไคลเอนต์ ไม่ใช่เซิร์ฟเวอร์ของคุณ เขียนลงว่าคุณรองรับไคลเอนต์ใดบ้าง (เว็บแอป, iOS, Android, API พาร์ทเนอร์, แอดมินภายใน) และจดสิ่งที่แต่ละหน้าจอหลักต้องการ ถ้า "รายละเอียดลูกค้า" เดียวกันต้องการฟิลด์และรูปแบบการเรียกต่างกันระหว่างไคลเอนต์ นั่นเป็นสัญญาณชัดเจนสำหรับการปรับรูปร่างเฉพาะไคลเอนต์
-
ทำแผนที่สิ่งที่คุณมีวันนี้ เอาเอนด์พอยต์ปัจจุบันและทำเครื่องหมายว่าส่วนไหนใช้ร่วม (การดำเนินการโดเมนหลักเช่น คำสั่งซื้อ การชำระเงิน ผู้ใช้) กับส่วนที่เป็นรูปร่างการนำเสนอ (สรุปแดชบอร์ด เพย์โหลด "โฮม" ที่รวมข้อมูล) ชิ้นส่วนที่ใช้ร่วมควรอยู่ในแบ็กเอนด์แกนหลัก ส่วนที่ปรับรูปร่างเพื่อนำเสนอเหมาะกับ BFF
-
ตัดสินใจว่าการปรับรูปร่างและกฎควรอยู่ที่ไหน ถ้าคุณต้องการแค่การกำหนดเส้นทาง auth ขีดจำกัดการเรียก แคช และการเปิดเผยสาธารณะ vs ภายใน เกตเวย์เป็นที่เหมาะสม หากคุณต้องการการประกอบจริง (เรียกหลายเซอร์วิส เปลี่ยนหกคำขอเป็นหนึ่ง การตอบกลับต่างกันตามแอป) ให้ใส่ตรรกะนั้นในโค้ด BFF เพื่อให้ทดสอบและอ่านได้ง่าย
-
เลือกกฎการเวอร์ชันและการยกเลิกที่คุณปฏิบัติตามได้ ตัวอย่าง: "ไม่อนุญาตการเปลี่ยนแปลงที่ทำลายโดยไม่สร้างเวอร์ชันใหม่ และฟิลด์ที่ยกเลิกจะอยู่ 90 วัน" กับแนวทางเกตเวย์เพียงอย่างเดียว คุณอาจเวอร์ชันพื้นผิวสาธารณะและแปลเบื้องหลัง กับ BFF คุณมักเก็บ API แกนให้เสถียรและเวอร์ชันเฉพาะเอนด์พอยต์ของ BFF ต่อลูกค้า
-
วางแผนการเปิดตัวและวัด ก่อนเปลี่ยนอะไร จับเมตริกพื้นฐาน: p95 latency จำนวนคำขอต่อหน้าจอ ขนาดเพย์โหลด และอัตราข้อผิดพลาด ปล่อยให้ร้อยละเล็กก่อน เปรียบเทียบก่อนหลัง แล้วขยาย
ตัวอย่างง่าย: ถ้าแอปมือถือของคุณปล่อยเป็นรายเดือน แต่เว็บพอร์ทัลปล่อยทุกวัน BFF มือถือขนาดเล็กสามารถปกป้องแอปจากการเปลี่ยนแปลงแบ็กเอนด์บ่อย ๆ ในขณะที่เว็บยังไปต่อได้เร็ว
ตัวอย่าง: เว็บพอร์ทัล + แอปมือถือที่มีความเร็วปล่อยต่างกัน
จินตนาการบริษัทที่มีพอร์ทัลลูกค้าบนเว็บและแอปภาคสนามบนมือถือ ทั้งสองต้องการข้อมูลแกนเดียวกัน: ลูกค้า งาน ใบแจ้งหนี้ และข้อความ พอร์ทัลเว็บเปลี่ยนสัปดาห์ละครั้ง แอปมือถืออัพเดตช้ากว่าเพราะต้องผ่านการทบทวนสโตร์และยังต้องทำงานได้ในสัญญาณอ่อน
ปัญหาปรากฏเร็ว ผู้ใช้มือถือต้องการการตอบสนองที่กะทัดรัด การเรียกน้อยลง และโฟลว์ที่รองรับการทำงานออฟไลน์ (เช่น ดาวน์โหลดงานของวันนี้ครั้งเดียวแล้วซิงก์การเปลี่ยนแปลงทีหลัง) พอร์ทัลเว็บโอเคกับการเรียกมากขึ้นและหน้าจอที่มีข้อมูลมากกว่าเพราะออนไลน์เสมอและอัพเดตได้ง่ายกว่า
ตัวเลือก A: เกตเวย์ API หน้าหนึ่งสำหรับบริการที่เสถียร
การเลือกแบบเกตเวย์ก่อนเก็บบริการแบ็กเอนด์ไว้เหมือนเดิม เกตเวย์จัดการการตรวจสอบตัวตน การกำหนดเส้นทาง และการปรับแต่งเล็กน้อย เช่น เฮดเดอร์ ขีดจำกัดอัตรา และการแมปฟิลด์ง่าย ๆ
การเวอร์ชันมักอยู่ที่ระดับ API ของเซอร์วิส ซึ่งอาจดีเพราะชิ้นส่วนเคลื่อนไหวน้อย แต่ก็หมายความว่าการเปลี่ยนแปลงเฉพาะมือถือมักจะผลักให้ต้องเวอร์ชันกว้าง ๆ เช่น /v2 เพราะเอนด์พอยต์พื้นฐานถูกใช้ร่วมกัน
การเปิดเผยเอนด์พอยต์ชัดเจนถ้าคุณมองว่าเกตเวย์เป็นประตูสาธารณะเดียว บริการภายในยังเป็นส่วนตัว แต่คุณต้องเข้มงวดว่าทางเกตเวย์เข้าถึงอะไรและเผยอะไร
ตัวเลือก B: Mobile BFF ที่พูดภาษามือถือ
กับ mobile BFF แอปมือถือคุยกับเอนด์พอยต์ที่ออกแบบมาสำหรับหน้าจอมือถือและโฟลว์ซิงก์ BFF สามารถรวบรวมข้อมูล (รายละเอียดงาน + ลูกค้า + ข้อความล่าสุด) ตัดฟิลด์ และส่งเพย์โหลดเดียวที่ตรงกับความต้องการของแอป
สิ่งที่เปลี่ยนไป:
- การเวอร์ชันง่ายขึ้นต่อไคลเอนต์: คุณสามารถเวอร์ชัน mobile BFF โดยไม่บังคับให้เว็บต้องขยับ
- ประสิทธิภาพมักดีขึ้นสำหรับมือถือ: รอบเรียกน้อยลงและการตอบกลับเล็กลง
- การแยกระหว่างสาธารณะและภายในชัดเจนขึ้น: BFF เป็นสาธารณะ แต่เรียกเซอร์วิสภายในที่ไม่จำเป็นต้องเปิดเผย
ข้อผิดพลาดและกับดักที่พบบ่อย
กับดักใหญ่ที่สุดคือปล่อยให้เกตเวย์กลายเป็นแบ็กเอนด์ย่อม ๆ เกตเวย์เก่งเรื่องการกำหนดเส้นทาง auth ขีดจำกัดและการปรับคำขอ แต่ถ้าคุณยัดกฎธุรกิจลงไปมาก มันจะทดสอบยาก แก้บั๊กยาก และแตกได้ง่ายจากการเปลี่ยนคอนฟิก
BFF ผิดพลาดในทางกลับกันเมื่อทีมสร้าง BFF หนึ่งตัวต่อหน้าจอหรือฟีเจอร์ และการบำรุงรักษาพังทลาย BFF ควรมักแมปกับประเภทไคลเอนต์ (เว็บ, iOS, Android) หรือขอบเขตผลิตภัณฑ์ชัดเจน ไม่ใช่ทุกมุม UI มิฉะนั้นคุณจะทำสำเนากฎซ้ำในหลายที่ และการเวอร์ชันกลายเป็นงานเต็มเวลา
ความผิดพลาดเรื่องการเวอร์ชันมักมาจากสองขั้ว ถ้าคุณเวอร์ชันทุกอย่างตั้งแต่วันแรก คุณจะทำให้ API แช่แข็งเร็วและเก็บรูปแบบเก่าไว้นานเกินไป ถ้าคุณไม่เคยเวอร์ชัน ในที่สุดคุณจะปล่อยการเปลี่ยนที่ทำลายโดยไม่ตั้งใจ กฎง่าย ๆ ที่ใช้ได้ผล: อย่าเวอร์ชันสำหรับการเปลี่ยนแปลงเพิ่มเท่านั้น แต่เวอร์ชันเมื่อคุณลบหรือเปลี่ยนความหมาย
การเปิดเผยเอนด์พอยต์ภายในคือจุดที่ทีมเจ็บตัว เปิดบริการภายในให้เข้าถึงอินเทอร์เน็ต (แม้ชั่วคราว) ทำให้การเปลี่ยนแปลงภายในกลายเป็นความเสี่ยงด้านความปลอดภัยหรือการล่ม เก็บพรมแดนชัดเจน: ให้เกตเวย์หรือ BFF เป็นสาธารณะเท่านั้นและบริการภายในอยู่ส่วนตัว
ปัญหาด้านประสิทธิภาพมักเกิดจากตัวเอง: เพย์โหลดใหญ่เกินไป หลายรอบเรียก และไม่มีงบสำหรับความหน่วง เช่น แอปมือถืออาจต้องการแค่สถานะคำสั่งซื้อและยอดรวม แต่ได้วัตถุคำสั่งซื้อเต็มรูปแบบที่มีทุกไลน์ไอเท็มและฟิลด์ audit ทำให้ทุกคำขอช้าบนเครือข่ายเซลลูลาร์
สัญญาณเตือนที่ควรระวัง:
- คอนฟิกเกตเวย์อ้างถึงแนวคิดธุรกิจเช่น "คุณสมบัติคืนเงิน" หรือ "กฎ VIP"
- BFF เพิ่มจำนวนเร็วกว่าจำนวนไคลเอนต์ที่มันให้บริการ
- คุณอธิบายกลยุทธ์การเวอร์ชัน API ไม่ได้ในหนึ่งประโยค
- เอนด์พอยต์ภายในเข้าถึงได้จากอินเทอร์เน็ตสาธารณะ
- การตอบกลับโตขึ้นเรื่อย ๆ เพราะ "อาจมีประโยชน์ในอนาคต"
เช็คลิสต์ด่วนและขั้นตอนถัดไป
ถ้าคุณติดในทางเลือก API gateway vs BFF ให้โฟกัสที่สิ่งที่จะพังก่อนในโลกจริง: การปล่อย เพย์โหลด และพรมแดนความปลอดภัย
เช็คลิสต์ด่วน
ถ้าคุณตอบ "ไม่" หลายข้อ จากด้านล่าง โครงสร้างปัจจุบันอาจทำร้ายเมื่อไคลเอนต์เติบโต:
- คุณเปลี่ยนเซอร์วิสเดียวโดยไม่บังคับให้ไคลเอนต์ทุกตัวอัพเดตในสัปดาห์เดียวได้หรือไม่?
- มีพรมแดนชัดเจนระหว่างเอนด์พอยต์สาธารณะ (ปลอดภัยสำหรับอินเทอร์เน็ต) และภายใน (สำหรับระบบที่เชื่อถือได้) หรือไม่?
- เว็บและมือถือได้รับแค่สิ่งที่ต้องการ (ไม่ใช่การตอบกลับ "ใส่หมด") หรือไม่?
- คุณสามารถปล่อยแบบค่อยเป็นค่อยไป (ร้อยละเล็กก่อน) และเห็นข้อผิดพลาด latency และทราฟฟิกที่ผิดปกติได้เร็วหรือไม่?
- คุณรู้ว่าใครเป็นเจ้าของสัญญาของแต่ละเอนด์พอยต์และใครอนุมัติการเปลี่ยนแปลงที่ทำลายหรือไม่?
ขั้นตอนถัดไป
เปลี่ยนคำตอบเป็นแผน เป้าหมายไม่ใช่สถาปัตยกรรมที่สมบูรณ์แบบ แต่เป็นการลดความประหลาดใจเมื่อปล่อย
เขียนสัญญา API เป็นภาษาธรรมดา (อินพุต เอาต์พุต รหัสข้อผิดพลาด สิ่งที่เปลี่ยนได้) เลือกรูปแบบความเป็นเจ้าของ: ใครเป็นเจ้าหน้าที่ความต้องการไคลเอนต์ (เว็บ/มือถือ) และใครเป็นเจ้าของบริการโดเมนแกนกลาง ตัดสินใจว่าการเวอร์ชันอยู่ที่ไหน (ต่อไคลเอนต์หรือศูนย์กลาง) และตั้งกฎการยกเลิกที่คุณจะปฏิบัติตาม
เพิ่มการมอนิเตอร์พื้นฐานก่อนรีแฟกใหญ่: อัตราคำขอ p95 latency อัตราข้อผิดพลาด และเอนด์พอยต์ที่มีขนาดเพย์โหลดใหญ่สุด ทดลองต้นแบบโฟลว์ที่เสี่ยงที่สุดก่อน
ถ้าคุณกำลังสร้างด้วย AppMaster (appmaster.io) แนวทางปฏิบัติหนึ่งคือเก็บตรรกะธุรกิจแกนกลางและโมเดลข้อมูลไว้ในแบ็กเอนด์ที่สร้างขึ้น แล้วเพิ่มเลเยอร์เกตเวย์หรือ BFF บาง ๆ เฉพาะเมื่อไคลเอนต์ต้องการการปรับรูปร่างเพย์โหลดหรือการแยกวงจรการปล่อยจริง ๆ
ถ้าเช็คลิสต์ตอบยาก ให้ถือเป็นสัญญาณว่าควรทำให้สัญญาง่ายขึ้นและรัดกุมการแยกระหว่างสาธารณะกับภายในก่อนจะเพิ่มเอนด์พอยต์ใหม่
คำถามที่พบบ่อย
เริ่มจาก API gateway เมื่อคุณต้องการจุดเข้าเดียวสาธารณะพร้อมการควบคุมร่วม เช่น การตรวจสอบตัวตน ขีดจำกัดการเรียก และการกำหนดเส้นทาง เพิ่ม BFF เมื่อเว็บและมือถือมีความต้องการเพย์โหลดต่างกันอย่างชัดเจน ต้องการลดจำนวนคำร้องขอจากไคลเอนต์ หรือมีรอบการปล่อยที่แยกกันได้
เกตเวย์เหมาะกับความกังวลข้ามระบบและการควบคุมทราฟฟิกที่ขอบระบบ ดังนั้นให้เก็บงานอย่างการกำหนดเส้นทาง การบังคับใช้ auth และการจัดการคำขอ/การตอบกลับขั้นพื้นฐานไว้ที่นั่น ส่วน BFF ควรทำการประสานงานสำหรับไคลเอนต์ เช่น การเรียกหลายบริการมารวมกันและตัดฟิลด์ที่ไม่จำเป็นไว้ แต่ยังไม่ควรกลายเป็นที่เก็บกฎธุรกิจหลัก
เกตเวย์ให้คุณเวอร์ชันที่ "ประตูหน้า" เดียว ซึ่งอธิบายง่ายแต่คุณอาจต้องรองรับเวอร์ชันเก่าเป็นเวลานาน ส่วน BFF ช่วยให้เวอร์ชันแยกตามไคลเอนต์ได้ ดังนั้นมือถืออาจคงสัญญาเดิมไว้ ขณะที่เว็บไปเร็วกว่า แต่ต้องแลกด้วยการดูแลหลายบริการและสัญญาหลายชุด
ตั้งค่าเริ่มต้นให้เป็นการเปลี่ยนแปลงที่ไม่ทำลาย เช่น เพิ่มฟิลด์ทางเลือกหรือเพิ่มเอนด์พอยต์ใหม่ ให้สร้างเวอร์ชันเมื่อคุณจะลบหรือเปลี่ยนชื่อฟิลด์ เปลี่ยนชนิดข้อมูล หรือเปลี่ยนความหมาย เพราะผู้ใช้มือถืออาจไม่อัพเดตแอปในทันที
เก็บบริการภายในให้เป็นส่วนตัวและเปิดเผยเฉพาะเกตเวย์หรือ BFF สู่อินเทอร์เน็ตสาธารณะ กรองการตอบกลับให้ไคลเอนต์ได้รับเฉพาะสิ่งที่ต้องการ และบังคับใช้การอนุญาตแบบแยกตามเส้นทางเพื่อป้องกันการเรียกใช้งานแอดมินโดยคนทั่วไป
ใช้ BFF เมื่อไคลเอนต์จะต้องทำหลายคำขอเรียงกัน เพราะการรวบรวมบนเซิร์ฟเวอร์และส่งกลับครั้งเดียวมักจะเร็วกว่าการทำหลายรอบบนเครือข่ายมือถือ เกตเวย์ก็เพิ่มฮอปภายในเช่นกัน จึงควรทำให้มันเบาและวัดผลความหน่วงและขนาดเพย์โหลดเสมอเพื่อหลีกเลี่ยงความช้าแอบแฝง
เกตเวย์เป็นจุดร่วม ดังนั้นคอนฟิกหรือการล่มที่ผิดพลาดอาจกระทบทุกไคลเอนต์พร้อมกัน BFF ลดรัศมีการระเบิดโดยแยกผลกระทบไปยังไคลเอนต์เดียว แต่คุณจะต้องดูแลการปล่อย การมอนิเตอร์ และพื้นที่ on-call ที่มากขึ้น
ใช้ correlation ID และส่งต่อมันผ่านเกตเวย์/BFF และบริการเบื้องหลังทั้งหมดเพื่อให้การกระทำของผู้ใช้หนึ่งรายการสามารถติดตามได้แบบ end-to-end ติดตามเมตริกสำคัญต่อเอนด์พอยต์ เช่น อัตราข้อผิดพลาด p95 latency ปริมาณการร้องขอ และขนาดเพย์โหลด เพื่อให้การลดลงของประสิทธิภาพปรากฏขึ้นอย่างรวดเร็ว
กับเกตเวย์ มักจะเกิดกับการยัดกฎธุรกิจลงในการตั้งค่า ทำให้ทดสอบยากและแตกได้ง่ายกับคอนฟิก ในขณะที่ความผิดพลาดของ BFF มักมาจากการสร้าง BFF มากเกินไป (เช่น ต่อหน้าจอ) ซึ่งทำให้การบำรุงรักษาพังทลายและการเวอร์ชันกลายเป็นภาระ
เก็บโมเดลข้อมูลหลักและกระบวนการธุรกิจไว้ในแบ็กเอนด์ที่คุณสร้าง แล้วเพิ่มเลเยอร์เกตเวย์หรือ BFF บาง ๆ เฉพาะเมื่อไคลเอนต์ต้องการการปรับรูปร่างเพย์โหลดหรือการแยกวงจรการปล่อยจริง ๆ ใน AppMaster มักหมายถึงการสร้างเอนด์พอยต์โดเมนที่มั่นคงใน Go backend ที่ถูกสร้างขึ้น แล้วเพิ่มเลเยอร์เล็ก ๆ สำหรับการรวมข้อมูลหรือการตัดฟิลด์สำหรับมือถือ


