System Design
คำถาม
จัดการเงื่อนไขที่นำไปแสดงผล ตรงนี้คือจุดสำคัญเลยครับ แทนที่เราจะให้หน้าเว็บดึงมาหมดทุกบทความ เราจะตั้งคำสั่งกรอง (Filter) ไว้ที่โค้ดฝั่งเว็บของเราว่า: ขอเฉพาะบทความที่ Type เป็น Blog และ ขอเฉพาะบทความที่ Status เป็น Published และ ขอเฉพาะบทความที่ Publish Date น้อยกว่าหรือเท่ากับ วันและเวลาปัจจุบัน (อิงตามโซนเวลา +07:00) ด้วยสมการง่ายๆ แค่นี้ ถ้าวันนี้คือวันที่ 17 มีนาคม 2569 ต่อให้เรากดเปลี่ยนสถานะบทความวันที่ 1 เมษายน เป็น Published เอาไว้ โค้ดของเราก็จะมองไม่เห็นบทความนั้นจนกว่าจะถึงเวลาที่กำหนดครับ หน้าเว็บก็จะนำไปแสดงผลเองโดยอัตโนมัติเมื่อถึงเวลา สรุปเงื่อนไขและระบบการทำงานของเว็บ: เงื่อนไขการเผยแพร่ (Filter): บทความจะไปโชว์บนเว็บได้ ต้องผ่านด่าน 3 ข้อพร้อมกัน คือ ประเภทถูกต้อง (Type = Blog) สถานะพร้อมเผยแพร่ (Status = Published) ถึงเวลาที่กำหนดแล้วจริงๆ (Publish Date <= วันและเวลาปัจจุบัน อิงตามเวลาไทย +07:00) ระบบตัวกลางอัปเดตข้อมูล (Syncing): จะมีระบบหลังบ้านคอยวิ่งไปเช็กข้อมูลกับ Notion ทุกๆ 1 ชั่วโมง เพื่อกวาดหาบทความที่เข้าเงื่อนไขทั้งหมด ดึงมาเก็บในบ้านตัวเอง (Database): พอเจอบทความที่ผ่านเกณฑ์ ระบบจะก๊อปปี้เนื้อหาจาก Notion มาเซฟลงใน Database ของเราเอง หน้าเว็บโหลดไวและเสถียร: ตัวเว็บ Next.js จะดึงข้อมูลจาก Database ของเราไปแสดงผลเท่านั้น ไม่มีการไปคุยกับ Notion โดยตรง ทำให้เว็บโหลดเร็วกว่ามากและรองรับคนเข้ามาอ่านเยอะๆ ได้สบาย แต่การที่เราตั้งเวลาซิงก์ทุกๆ 1 ชั่วโมง แปลว่าเราจะมี "ช่องโหว่เรื่องเวลา" ครับ สมมติว่าวันนึงเรากด Published ไปแล้ว แล้วเพิ่งเห็นว่าพิมพ์ข้อมูลสำคัญผิดพลาดร้ายแรง พอเราวิ่งกลับไปแก้ใน Notion ทันที... หน้าเว็บของเราก็ยังจะโชว์เนื้อหาที่ผิดนั้นต่อไปจนกว่าจะถึงรอบซิงก์ชั่วโมงถัดไป นอกจากนี้ ถ้าเราเปลี่ยนใจอยาก "ซ่อน" หรือเปลี่ยนสถานะบทความกลับไปเป็น Draft ระบบหลังบ้านที่ทำหน้าที่ก๊อปปี้ข้อมูลมา จะรู้ไหมว่าต้องตามไปซิงก์เพื่อ "ลบหรืออัปเดต" บทความนั้นออกจาก Database ของเราด้วย? คำถามชวนคิด: ในขั้นตอนการทำ Syncing เราได้เตรียมแผนสำหรับทำปุ่ม "อัปเดตด่วน (Manual Sync)" ในกรณีฉุกเฉิน หรือเตรียม Logic ให้ระบบรู้จักการ "อัปเดต/ลบ" (Update/Delete) บทความเก่าที่เคยดึงมาแล้ว ไม่ใช่แค่การ "เพิ่ม" (Insert) อย่างเดียว ทำยังไงดี
คำถามนี้คือ ปัญหาคลาสสิกของระบบ Sync ระหว่าง CMS (Notion) กับ Database ของเว็บ เลยครับ 👍
หลักๆ ต้องออกแบบให้รองรับ 3 อย่างพร้อมกัน
1️⃣ Insert (บทความใหม่)
2️⃣ Update (บทความที่แก้ไขแล้ว)
3️⃣ Delete / Unpublish (บทความที่ถูกซ่อนหรือเปลี่ยนสถานะ)
และควรมี Manual Sync สำหรับกรณีฉุกเฉิน
ผมจะแนะนำ โครงสร้างระบบที่ใช้จริงกับ Next.js + Notion API ที่เสถียรครับ
1. หลักการ Sync ที่ถูกต้อง (Upsert Strategy)
อย่าใช้แค่ Insert
ให้ใช้แนวคิด Upsert
Flow การ Sync
2. Filter จาก Notion ก่อน
กรองตั้งแต่ตอน Query API
ตัวอย่าง Notion API filter
จะได้เฉพาะบทความที่ควรแสดง
3. Sync Algorithm (สำคัญที่สุด)
ตัวอย่าง Logic
ผลลัพธ์
สถานการณ์ | ระบบทำอะไร |
บทความใหม่ | Insert |
แก้ไขบทความ | Update |
เปลี่ยน Draft | Delete |
เปลี่ยน Publish Date อนาคต | Delete |
ลบบทความใน Notion | Delete |
4. Manual Sync (ปุ่มอัปเดตด่วน)
ทำ API route
Next.js ตัวอย่าง
แล้วสร้างปุ่มใน Admin
หรือเรียกด้วย curl
5. ลดปัญหา Sync Delay (1 ชั่วโมง)
มี 3 วิธี
วิธีที่ 1 (ง่ายสุด)
cron job
เช่น
วิธีที่ 2 (แนะนำ)
Sync ทุก
โหลด Notion API น้อยมาก
วิธีที่ 3 (เทพสุด)
ใช้ Notion Webhook
แต่ Notion ยังไม่มี webhook จริง
ต้องใช้ middleware เช่น
Trigger
จะ Sync ทันที
6. ป้องกัน Content ผิดพลาด (Emergency Fix)
เพิ่มระบบ Cache Bust
เช่น
หรือ
ใน Next.js
7. Architecture ที่เสถียรสุด
แนะนำแบบนี้
ข้อดี
✅ เว็บเร็ว
✅ รองรับคนอ่านเยอะ
✅ Notion ไม่โดนยิง API
✅ แก้บทความแล้ว Sync ได้
✅ มี Manual Sync
8. Trick ที่ Dev มืออาชีพใช้
เก็บ field นี้เพิ่ม
จาก Notion
แล้ว Sync เฉพาะที่ แก้ล่าสุด
ตัวอย่าง
จะประหยัด API มาก
9. Schema Database แนะนำ
สรุปแนวคิดระบบ
Filter
Sync Logic
ระบบควรมี
✅ Cron Sync
✅ Upsert Logic
✅ Delete Logic
✅ Manual Sync
✅ lastEdited Optimization
Next.js + Notion เป็น CMS สามารถวาด Architecture ระดับ Production (แบบที่ใช้จริงกับเว็บใหญ่) เช่น
- Instant Publish
- ISR Cache
- Queue Worker
- Webhook Sync
- 10k+ บทความยังเร็ว
โครงระบบระดับ Production