ปุ่มมันกดไม่ได้จริง แต่ไม่มีใครบังคับให้ลูกค้าใช้ปุ่ม
ทุกอย่างที่วิ่งบนเครื่องผู้ใช้เป็นแค่ข้อเสนอแนะ ใครก็ copy as curl แล้วยิงตรงได้ กฎจริงต้องอยู่ฝั่งเซิร์ฟเวอร์และฐานข้อมูล อย่ารับราคามาจากฝั่งลูกค้า และเทสต์ต้องยิง API ตรง
มีออร์เดอร์เข้ามาด้วยราคาโปรที่หมดไปตั้งแต่เมื่อวาน
เปิดหน้าเว็บดู โปรหมดแล้วจริง ปุ่มเป็นสีเทา กดไม่ได้ ลองกดดูสิบรอบ ไม่มีอะไรเกิดขึ้น
แล้วก็สรุปกับตัวเองว่าคงเป็นจังหวะพอดีตอนหมดเขต
ไม่ใช่จังหวะ
เขาไม่ได้กดปุ่ม
หน้าเว็บที่เราเขียน เป็นแค่สิ่งที่วิ่งอยู่บนเครื่องของคนอื่น เขาเปิด devtools ดูได้ว่าตอนกดสั่งซื้อ มันยิงไปที่ไหน ส่งอะไรไป แล้วยิงเองตรง ๆ ก็ได้ ไม่ต้องผ่านหน้าจอเลย
ไม่ต้องเป็นแฮกเกอร์ เปิดแท็บ network ดู แล้วกด copy as curl ปุ่มเดียว
เราไม่เคยเจอ เพราะเราทดสอบผ่านหน้าจอเสมอ และหน้าจอเราก็เขียนให้มันกันไว้แล้ว
หลักการมีข้อเดียว
ทุกอย่างที่วิ่งอยู่บนเครื่องของผู้ใช้ คือข้อเสนอแนะ ไม่ใช่กฎ
กฎมีที่เดียวคือฝั่งเซิร์ฟเวอร์ ทุกเงื่อนไขที่เช็กบนหน้าจอ ต้องมีอีกชุดที่เช็กซ้ำหลังบ้าน
ไม่ใช่เพราะไม่ไว้ใจลูกค้า แต่เพราะหน้าจอไม่ได้อยู่ในมือเราแล้ว
ทำจริงมีสามชั้น แต่ละชั้นทำหน้าที่ต่างกัน
ชั้นแรก เช็กบนหน้าจอ
ชั้นนี้มีไว้เพื่อความรู้สึกล้วน ๆ บอกผู้ใช้ตั้งแต่เนิ่น ๆ ว่ากรอกผิด ไม่ต้องรอส่งแล้วเด้งกลับ มันช่วยเรื่อง UX ล้วน ๆ กันอะไรไม่ได้เลยสักอย่าง
ชั้นที่สอง เช็กที่เซิร์ฟเวอร์
ชั้นนี้คือกฎจริง ราคาต้องคิดจากฐานข้อมูล ไม่ใช่รับตัวเลขที่ลูกค้าส่งมา สิทธิ์ต้องเช็กจาก session ไม่ใช่จากค่าที่แนบมาใน request วันหมดเขตต้องเทียบกับเวลาของเซิร์ฟเวอร์
ถ้าจำอะไรได้ข้อเดียวจากโพสต์นี้ เอาข้อนี้ อย่ารับราคามาจากฝั่งลูกค้า
ชั้นที่สาม ล็อกที่ฐานข้อมูล
unique constraint, foreign key, check constraint ชั้นนี้ไม่สวย ไม่มีใครเห็น แต่เป็นชั้นเดียวที่ยังยืนอยู่ตอนโค้ดหลังบ้านมีรูที่เราไม่รู้
จำง่าย ๆ ชั้นบนบอก ชั้นกลางตัดสิน ชั้นล่างการันตี
ทีนี้เรื่องที่เกี่ยวกับ AI โดยตรง
เราเปิดไฟล์ component ของฟอร์มให้ AI ดู แล้วบอกว่า "ใส่ validation ให้หน่อย"
มันก็ใส่ให้ในฟอร์ม เพราะนั่นคือไฟล์ที่เราเปิดให้มันดู
มันไม่รู้ว่า API ของเราเปิดรับจากทุกที่ ถ้าเราไม่บอก มันเห็นแค่ไฟล์ที่เราเปิด
เอาไปใช้วันนี้ เริ่มจากทดสอบก่อน
เปิดแอปตัวเอง เปิด devtools ไปแท็บ network แล้วทำสิ่งที่สำคัญที่สุดหนึ่งครั้ง สั่งซื้อ สมัคร อะไรก็ได้
คลิกขวาที่ request นั้น เลือก copy as curl แล้วเอาไปวางใน terminal
แก้ตัวเลขสักตัวให้มันผิด ราคาให้ถูกลง จำนวนให้ติดลบ id ให้เป็นของคนอื่น แล้วกด enter
ถ้ามันผ่าน แปลว่าหน้าจอเป็นสิ่งเดียวที่กันอยู่
แล้วบอก AI แบบนี้
ไล่ validation ในโปรเจกต์นี้ให้หน่อย
- ลิสต์ทุกเงื่อนไขที่เช็กอยู่ฝั่ง client ออกมาก่อน
- ทุกข้อในลิสต์นั้น ต้องมีชุดที่เช็กซ้ำฝั่ง server ด้วย บอกด้วยว่าข้อไหนยังไม่มี
- ราคาและสิทธิ์: ห้ามอ่านจาก request ให้อ่านจาก database กับ session เท่านั้น
- ใส่ constraint ที่ database เป็นชั้นสุดท้าย
- เขียนเทสต์ที่ยิง API ตรง ๆ ไม่ผ่าน UI แล้วส่งค่าที่ควรถูกปฏิเสธ assert ว่าโดนปฏิเสธจริง
ข้อสุดท้ายสำคัญที่สุด เทสต์ที่กดผ่านหน้าจอจะผ่านตลอด เพราะหน้าจอคือสิ่งที่เรากันไว้แล้ว