JSONPath หรือ JSON Pointer
สรุปสำคัญ: JSON Pointer คือที่อยู่ที่ไม่ซ้ำซึ่งเก็บเป็นคีย์ได้; JSONPath คือภาษา query การเลือกใช้ผิดจะทำให้การอัปเดต config พังหรือต้องสร้าง JSONPath ที่ไม่สมบูรณ์ขึ้นมาเอง

สรุปสั้น ๆ: ใช้ JSON Pointer เมื่อต้องอ่าน เขียน หรือเก็บที่อยู่ของ node เดียว (เช่น /server/cors/0) และใช้ JSONPath เมื่อต้องเลือกชุด node ตามเงื่อนไข; path ที่ถูกเก็บไว้ควรเป็น Pointer เสมอ ไม่ใช่นิพจน์
ถามตัวเองก่อนว่าต้องการ node เดียวหรือชุดของ node
ในตารางเดียว
| JSON Pointer | JSONPath | |
|---|---|---|
| ธรรมชาติ | ที่อยู่ที่ไม่ซ้ำ | นิพจน์ query |
| ไวยากรณ์ | /a/b/0 |
$.a.b[0], $..price |
| ผลลัพธ์ | node เดียวเท่านั้น หรือไม่มีเลย | ศูนย์หรือมากกว่า node |
| เก็บเป็นคีย์ได้ | ได้ สตริงคือ identity | ไม่ได้ อาจตรงหลาย node |
| มาตรฐาน | RFC 6901 | RFC 9535 (สรุปในปี 2024) |
JSON Pointer
/server/host -> "127.0.0.1"
/server/cors/0 -> "https://a.com"
/ -> the whole document
คีย์ที่มี / หรือ ~ ต้อง escape: ~0 สำหรับ ~, ~1 สำหรับ / จุดแข็งคือความแน่นอน: ที่อยู่เป็นสตริง จึงใส่ในคอลัมน์ฐานข้อมูล บรรทัด log หรือคีย์ config ได้ JSON Patch (RFC 6902) ใช้วิธีนี้ระบุทุก operation
JSONPath
$.store.book[*].author
$..price
$.store.book[?(@.price < 10)]
ใกล้กับ WHERE ของ SQL นิพจน์เดียวกันคืนศูนย์ หนึ่ง หรือหนึ่งร้อย node ขึ้นกับข้อมูล
รูปแบบความล้มเหลวสองแบบ
ใช้ JSONPath เป็นคีย์ config เก็บ $.server.port แล้ววันหนึ่งโครงสร้างกลายเป็นอาร์เรย์ นิพจน์นั้นก็ตรงกับ port หลายตัว และตรรกะอัปเดตไม่มีทางเลือกได้
ใช้ Pointer เพื่อเลือก "หา node ทั้งหมดที่ price ต่ำกว่า 10" เป็นไปไม่ได้ด้วย pointer การเขียนลูปเองหมายถึงการสร้าง JSONPath บางส่วนขึ้นมา
ระบบจริงแบ่งงานกันอย่างไร
- การอ่าน config, การอัปเดตฟิลด์, patch: Pointer คงที่และตรวจสอบได้
- การสำรวจข้อมูล, การดึงข้อมูลจำนวนมาก, การทำรายงาน: JSONPath เน้นความสามารถในการแสดงออก
- อะไรที่ถูกเก็บไว้: Pointer เท่านั้น ไม่ใช่นิพจน์
คำถามที่พบบ่อย
ควรเลือกระหว่าง JSON Pointer กับ JSONPath อย่างไร?
ถามว่าต้องการ node เดียวหรือชุด ใช้ JSON Pointer เพื่ออ่านหรือเขียน node เดียวและเก็บที่อยู่นั้นเป็นคีย์ เพราะ pointer ไม่ซ้ำ เช่น /server/cors/0 ใช้ JSONPath เพื่อเลือก node ตามเงื่อนไข เช่น $.store.book[?(@.price < 10)]
ทำไมนิพจน์ JSONPath ใช้เป็นคีย์ config ไม่ได้?
เพราะนิพจน์อาจตรงกับหลาย node เก็บ $.server.port แล้ววันหนึ่งโครงสร้างกลายเป็นอาร์เรย์ นิพจน์นั้นก็ตรงกับ port หลายตัว และตรรกะอัปเดตตัดสินไม่ได้ว่าจะแก้ตัวไหน อะไรที่ถูกเก็บหรือ audit ต้องใช้ Pointer
JSON Pointer กรอง node ตามเงื่อนไขได้ไหม?
ไม่ได้ pointer เดินได้แค่ path ที่กำหนดและไม่รู้ว่ามี node ใดอยู่ การเลือกทุก node ที่ price ต่ำกว่า 10 จึงเป็นไปไม่ได้ การเขียนลูปเองหมายถึงสร้าง JSONPath บางส่วนขึ้นมา