สมอง SML

คลังความรู้ / การตัดสินใจ (ADR)

#backend#adr#query-gateway#api

ADR-0005 Query Gateway เริ่มแบบอ่านอย่างเดียว

สถานะ: accepted (ส่วนสัญญา read ยังตรงกับโค้ด) แต่ข้อความ "/query/exec ยังใช้ไม่ได้" ล้าสมัยแล้ว — ปัจจุบัน /query/exec และ /query/execBatch มีใช้งาน (ดู ADR-0009 /query/execBatch เขียนหลาย statement ใน transaction เดียว (atomic) และ ADR-0011 ล็อก SQL เขียนจาก browser: ตารางเงิน/สต๊อก/GL ผ่าน /api/process เท่านั้น; เส้นทางอยู่ที่ router.go:90-103).

ทำงานอย่างไร

  1. ตัดสินใจทำฝั่งอ่านก่อน: POST /query/list และ POST /query/limit รับเฉพาะ SELECT/WITH ข้อเดียว (ErrNotSelectOnly, domain/query/query.go:23).
  2. เส้นทางแบน ไม่มี prefix /rest/v1 (เหมือน /auth, /admin) และเปลี่ยนชื่อพารามิเตอร์แบ่งหน้าเป็น offset / limit / includeTotal (แทน startRecord/maxRecords/countTotalRecord ของระบบเดิม) — ...0005...md:7.
  3. จำนวนรวมของ /query/limit ให้เซิร์ฟเวอร์ห่อ query เอง: SELECT count(*) FROM (<query>) AS _query_count (domain/query/query.go:318-319) — ใน ADR เขียน alias _cnt แต่ โค้ดใช้ _query_count (เอกสารคลาดเคลื่อนเล็กน้อย; ยึดโค้ด).
  4. ไม่มี wire-level compatibility shim กับ SOAP/REST เดิม (_query, _queryList, _queryListGetData, _queryLimit, /select, /selectgroup) — client เก่าต้องเขียนใหม่ (...0005...md:17).

ตัวเลือกที่ไม่เลือก / เลื่อนไว้

  • คงสัญญา _queryLimit แบบสอง query (data + count): เสี่ยง query สองตัวเพี้ยนกันและเพิ่มพื้นที่ที่ต้อง validate.
  • batch endpoint: เลื่อน แล้วภายหลังทำใน ADR-0008 /query/batch รัน SELECT หลายตัวในคำขอเดียว.
  • ฟีเจอร์ replace/Thai word-break (ICU) ของ /select เดิม: เลื่อน เป็นฟีเจอร์แยก.

ข้อควรระวัง

  • การบังคับ SELECT-only เป็น lexer + regex ไม่ใช่ SQL parser (scanSQL, query.go:94) ADR ยอมรับว่าอาจถูก bypass ด้วย SQL แปลก ๆ ได้ ขอบเขตความเชื่อใจจริงคือสิทธิ์ของ DB user — ดู Query Gateway: /query/list, limit, batch, exec, execBatch.
  • ปัจจุบันมี forbiddenSelectPattern (เช่น INTO, pg_sleep, dblink, copy) เพิ่มจากที่ ADR กล่าว (query.go:59).

ที่มาในโค้ด

  • backend/docs/adr/0005-query-gateway-read-only-first.md:7 — การตัดสินใจและ rename ของพารามิเตอร์.
  • backend/internal/domain/query/query.go:23 — ErrNotSelectOnly.
  • backend/internal/domain/query/query.go:318 — CountQuery() ห่อด้วย _query_count.
  • backend/internal/adapter/inbound/http/router.go:90 — กลุ่มเส้นทาง /query.

ดูเพิ่ม

Query Gateway: /query/list, limit, batch, exec, execBatch · ADR-0008 /query/batch รัน SELECT หลายตัวในคำขอเดียว · ADR-0006 /query/exec รับเฉพาะ DML + ตารางระบบต้อง level>=9 (ถูกแทนด้วย ADR-0011) · สารบัญ ADR ของ backend (Architecture Decision Records)