ในโลกของการพัฒนาแอปพลิเคชันที่ซับซ้อน การจัดการข้อมูลที่มาจากฟอร์มเดียวแต่มีวัตถุประสงค์หลายอย่าง (เช่น การดูตัวอย่างข้อมูลก่อนบันทึก หรือการบันทึกข้อมูลจริง) เป็นความท้าทายหลักทางสถาปัตยกรรม การพึ่งพา Logic ที่ฝั่ง Client (JavaScript) เพียงอย่างเดียวอาจทำให้เกิดช่องโหว่ด้านความปลอดภัยและความไม่สอดคล้องของข้อมูล
ในฐานะ System Specialist เราจึงต้องย้ายการควบคุมการทำงานทั้งหมดมาที่ Backend ซึ่งก็คือ PostgreSQL นี่คือแนวทางในการออกแบบระบบที่ใช้ฟังก์ชันเดียวในการจัดการทั้งการ ‘Preview’ (ตรวจสอบ) และ ‘Save’ (บันทึก) เพื่อรับประกันความสมบูรณ์ของข้อมูล (Data Integrity) ตั้งแต่ต้นทาง
💡 หลักการออกแบบ: การใช้ Parameter Mode ใน PostgreSQL
แทนที่จะสร้าง API หรือฟังก์ชันแยกกันสำหรับ ‘Preview’ และ ‘Save’ เราสามารถออกแบบฟังก์ชัน PostgreSQL เพียงตัวเดียวที่รับพารามิเตอร์สถานะ (Mode) เข้ามาด้วย ฟังก์ชันนี้จะทำหน้าที่เป็น Single Source of Truth โดยจะตรวจสอบค่าของ Mode ก่อนตัดสินใจว่าจะดำเนินการแค่การตรวจสอบความถูกต้อง (Validation/Select) หรือดำเนินการบันทึกข้อมูลจริง (Insert/Update)
⚙️ ตัวอย่างการใช้งาน PL/pgSQL Function
เราจะสร้างฟังก์ชันที่รับค่าข้อมูล JSON (จำลองข้อมูลจากฟอร์ม) และค่า Mode (‘preview’ หรือ ‘save’) เข้ามา:
SQL
-- 1. สร้างตารางสำหรับเก็บข้อมูล (สมมติ) --
CREATE TABLE user_submissions (
id SERIAL PRIMARY KEY,
data_key TEXT NOT NULL,
data_value TEXT NOT NULL,
submission_mode TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 2. สร้างฟังก์ชันหลักที่จัดการหลายโหมด --
CREATE OR REPLACE FUNCTION process_form_submission(
p_data JSONB,
p_mode TEXT
) RETURNS JSONB AS $$
DECLARE
v_status TEXT := '';
BEGIN
IF p_mode = 'preview' THEN
-- โหมด Preview: ตรวจสอบความถูกต้องของข้อมูลเท่านั้น (SELECT/VALIDATE)
-- เราสามารถตรวจสอบว่าข้อมูลที่ส่งมามีรูปแบบที่ถูกต้องหรือไม่ โดยไม่บันทึก
IF p_data->>'data_key' IS NULL OR p_data->>'data_value' IS NULL THEN
RETURN jsonb_build_object('success', FALSE, 'message', 'Preview failed: Missing required data.');
END IF;
-- หากผ่านการตรวจสอบ จะส่งข้อความยืนยันว่าข้อมูลพร้อมสำหรับการบันทึก
RETURN jsonb_build_object('success', TRUE, 'message', 'Preview successful. Data is valid for saving.');
ELSIF p_mode = 'save' THEN
-- โหมด Save: ดำเนินการบันทึกข้อมูลจริง (INSERT/UPDATE)
INSERT INTO user_submissions (data_key, data_value, submission_mode)
VALUES (p_data->>'data_key', p_data->>'data_value', p_mode);
RETURN jsonb_build_object('success', TRUE, 'message', 'Data saved successfully.');
ELSE
-- กรณีโหมดไม่ถูกต้อง
RETURN jsonb_build_object('success', FALSE, 'message', 'Invalid submission mode specified.');
END IF;
END;
$$ LANGUAGE plpgsql;
-- 3. ตัวอย่างการเรียกใช้ (Scenario 1: Preview)
SELECT process_form_submission('{"data_key": "apple", "data_value": "1,2,3"}', 'preview');
-- 4. ตัวอย่างการเรียกใช้ (Scenario 2: Save)
SELECT process_form_submission('{"data_key": "banana", "data_value": "4,5,6"}', 'save');
✅ ประโยชน์ทางสถาปัตยกรรม
การใช้ฟังก์ชันแบบนี้ทำให้เกิดประโยชน์สูงสุดในหลายมิติ:
- Single Entry Point: ทุกการส่งข้อมูลจะถูกจัดการที่ฟังก์ชันเดียว ทำให้ง่ายต่อการบำรุงรักษาและการตรวจสอบ (Auditability)
- Data Integrity: โหมด ‘preview’ ช่วยให้เราสามารถรัน Logic การตรวจสอบความถูกต้อง (Validation Logic) ที่ซับซ้อนได้ก่อนที่ข้อมูลจะถูกเขียนลงฐานข้อมูลจริง
- Security: ลดความเสี่ยงจากการที่ Client-side Logic ถูกข้ามไปได้ เพราะการตัดสินใจทั้งหมดเกิดขึ้นที่ระดับ Database (Server-side)
🚀 บทสรุป
การจัดการฟอร์มที่มีหลายสถานะใน PostgreSQL ไม่ได้หมายถึงการเขียนโค้ดหลายส่วน แต่หมายถึงการออกแบบ Logic ที่ชาญฉลาดภายในฟังก์ชันเดียว การใช้พารามิเตอร์ ‘Mode’ เป็นกลไกที่ทรงพลังในการแยกการทำงานระหว่างการตรวจสอบ (Preview) และการบันทึก (Save) อย่างชัดเจน ทำให้ระบบของคุณมีความเสถียร ปลอดภัย และเป็นไปตามหลักการของ Senior Architect ในการออกแบบระบบฐานข้อมูลที่แข็งแกร่ง