Pagination แบบ Cursor-Based vs Offset: API ควรเลือกใช้แบบไหน

การเปรียบเทียบการแบ่งหน้าแบบใช้เคอร์เซอร์กับการแบ่งหน้าแบบใช้ Offset: การเลื่อนหน้า, ต้นทุนของ Offset ที่ลึก, SQL แบบ Keyset, ตัวอย่างจาก Stripe และ Slack, และวิธีการทดสอบทั้งสองแบบใน Apidog

INEZA Felin-Michel

INEZA Felin-Michel

31 August 2026

Pagination แบบ Cursor-Based vs Offset: API ควรเลือกใช้แบบไหน

Apidog สำหรับองค์กร

การติดตั้งแบบ On-Premises

SSO & RBAC

รองรับมาตรฐาน SOC 2

สำรวจ Apidog Enterprise

ทุกๆ ปลายทางรายการจะต้องเจอกับคำถามเดียวกัน: จะแบ่งคำสั่งซื้อ 2 ล้านรายการออกเป็นหน้าๆ ให้ไคลเอนต์เรียกดูได้อย่างไร? เลือกการแบ่งหน้าแบบ Offset แล้วคุณจะได้ SQL ที่เรียบง่ายพร้อมหมายเลขหน้าที่ผู้ใช้เข้าใจ เลือกการแบ่งหน้าแบบ Cursor-based แล้วคุณจะได้ผลลัพธ์ที่เสถียรพร้อมความหน่วงที่คงที่ในทุกระดับความลึก แต่คุณจะเสียความสามารถในการ "ข้ามไปยังหน้า 47" ไป

ทีมส่วนใหญ่เลือก Offset เพราะเป็นค่าเริ่มต้นในทุกบทเรียน จากนั้นเมื่อตารางคำสั่งซื้อมีข้อมูลหลายล้านแถว หน้าที่ 4,000 ก็เริ่มหมดเวลา และผู้ใช้รายงานว่าเห็นข้อมูลซ้ำกันสองครั้งขณะเลื่อนดู คู่มือนี้จะครอบคลุมวิธีการทำงานของทั้งสองสไตล์ ข้อจำกัดของ Offset เหตุใด Stripe และ Slack จึงใช้ Cursor และวิธีการทดสอบทั้งสองสไตล์ด้วยคำขอแบบลูกโซ่ใน Apidog เมื่ออ่านจบ คุณจะทราบได้อย่างชัดเจนว่ารูปแบบใดเหมาะสมกับปลายทางของคุณ

หากคุณต้องการภาพรวมที่กว้างขึ้นก่อน คู่มือการแบ่งหน้า API ของเราครอบคลุมทุกกลยุทธ์แบบเปรียบเทียบ บทความนี้จะเจาะลึกสองกลยุทธ์ที่สำคัญที่สุด

การแบ่งหน้าแบบ Offset ทำงานอย่างไร

การแบ่งหน้าแบบ Offset จะจับคู่โดยตรงกับ SQL ไคลเอนต์ส่งหมายเลขหน้าและขนาดหน้า; เซิร์ฟเวอร์จะแปลงเป็น LIMIT และ OFFSET

SELECT id, customer_id, total_cents, created_at
FROM orders
ORDER BY created_at DESC
LIMIT 25 OFFSET 50;

การคิวรีนั้นจะส่งคืนหน้า 3 ของรายการคำสั่งซื้อของคุณ โดยมี 25 แถวต่อหน้า คำขอจะมีลักษณะดังนี้:

GET /v1/orders?page=3&per_page=25

และนี่คือการตอบกลับทั่วไป:

{
  "data": [
    {
      "id": "ord_8821",
      "customer_id": "cus_1932",
      "total_cents": 4599,
      "created_at": "2026-08-30T14:22:07Z"
    }
  ],
  "page": 3,
  "per_page": 25,
  "total": 1848203,
  "total_pages": 73929
}

ข้อดีนั้นชัดเจน ไคลเอนต์สามารถข้ามไปยังหน้าใดก็ได้ เซิร์ฟเวอร์สามารถส่งคืนจำนวนรวมได้ นักพัฒนาคนใดก็สามารถสร้างมันขึ้นมาได้ภายในบ่ายวันเดียว สำหรับตารางผู้ดูแลระบบขนาดเล็ก นี่คือตัวเลือกที่เหมาะสม และ คู่มือการแบ่งหน้าใน REST API แบบทีละขั้นตอนของเราจะอธิบายการสร้าง Offset แบบเต็มรูปแบบ

แต่ Offset มีปัญหาโครงสร้างสองประการ ซึ่งทั้งสองประการไม่ปรากฏในการพัฒนา แต่จะปรากฏในการใช้งานจริง

ปัญหาที่ 1: การเลื่อนของหน้า (Page drift)

Offset นับแถวจากด้านบนของผลลัพธ์ที่จัดเรียงไว้ ไม่ทราบว่าไคลเอนต์เห็นแถวใดไปแล้วบ้าง ดังนั้นเมื่อมีการแทรกหรือลบแถวระหว่างคำขอ หน้าต่างๆ ก็จะเลื่อนไปจากที่ไคลเอนต์เคยเห็น

สมมติว่าผู้ใช้โหลดหน้า 1 ของคำสั่งซื้อที่จัดเรียงจากใหม่สุดไปเก่าสุด แถวที่ 1 ถึง 25 ขณะที่พวกเขากำลังอ่าน มีคำสั่งซื้อใหม่ 3 รายการเข้ามา พวกเขาขอหน้า 2 ซึ่งคือ OFFSET 25 แถวที่ 23, 24 และ 25 จากการตอบกลับครั้งแรกถูกดันลงไปอยู่ที่ตำแหน่ง 26 ถึง 28 ตอนนี้ผู้ใช้เห็นแถวเหล่านั้นอีกครั้ง เกิดรายการซ้ำซ้อน

การลบจะทำให้เกิดผลตรงกันข้าม ลบ 3 แถวออกจากหน้า 1 ขณะที่ผู้ใช้กำลังอ่าน และ OFFSET 25 จะข้าม 3 แถวที่ผู้ใช้ไม่เคยเห็นไป เกิดการสูญหายของข้อมูลโดยไม่มีข้อผิดพลาด และไม่มีใครได้รับแจ้ง

สำหรับรายงานรายเดือนที่ไม่มีใครเลื่อนดูแบบเรียลไทม์ การเลื่อนของหน้า (drift) ไม่เป็นอันตราย สำหรับฟีดกิจกรรม ปลายทางสำหรับการซิงค์ หรือสิ่งใดก็ตามที่สคริปต์เรียกดูหน้าทีละหน้าในขณะที่การเขียนข้อมูลยังคงดำเนินอยู่ การเลื่อนของหน้าหมายถึงข้อมูลที่ซ้ำซ้อนหรือขาดหายไป ซึ่งผู้ใช้งานจะสังเกตเห็นได้

ปัญหาที่ 2: การทำ Offset ลึกๆ จะสแกนข้อมูลทั้งหมดที่ข้ามไป

OFFSET 500000 ไม่ได้เป็นการเคลื่อนย้ายไปยังแถวที่ 500,001 โดยตรง ฐานข้อมูลจะไล่ดัชนีผ่านข้อมูลครึ่งล้านรายการ ทิ้งข้อมูลเหล่านั้นไป แล้วจึงส่งคืน 25 แถวของคุณ ค่าใช้จ่ายจะเพิ่มขึ้นตามความลึกแบบเชิงเส้น: O(n) โดยที่ n คือค่า offset

ตัวเลขจริงจะทำให้เรื่องนี้ชัดเจนขึ้น ในตารางคำสั่งซื้อของ Postgres ที่มี 2 ล้านแถวและมีดัชนีบน created_at:

บทความเกี่ยวกับการไม่ใช้ Offset ของ Markus Winand ใน Use The Index, Luke สาธิตค่าใช้จ่ายนี้ด้วยแผนการคิวรีและคุ้มค่าที่จะอ่านทั้งหมด รูปแบบในการผลิตคือบันทึกการคิวรีที่ช้าซึ่งมีคำขอ offset สูงเป็นส่วนใหญ่ ซึ่งมักจะมาจาก crawler ตัวเดียวที่กำลังเดินสำรวจทุกหน้าของ API สาธารณะของคุณอย่างขยันขันแข็ง ลูกค้ารายเดียว และค่า p99 ของคุณก็เพิ่มขึ้นเป็นสองเท่า

การแบ่งหน้าแบบ Cursor-based ทำงานอย่างไร

การแบ่งหน้าแบบ Cursor-based หรือที่เรียกว่า Keyset Pagination จะละทิ้งตัวนับแถว แทนที่จะบอกว่า “ข้าม 50 แถว” ไคลเอนต์จะบอกว่า “ให้ฉันดูแถวหลังจากบันทึกเฉพาะนี้” Cursor จะระบุแถวสุดท้ายที่ไคลเอนต์เห็น เพื่อให้เซิร์ฟเวอร์สามารถค้นหาชุดข้อมูลถัดไปได้โดยตรง

SQL ใช้การเปรียบเทียบแถวบนคีย์การจัดเรียงแทน OFFSET:

SELECT id, customer_id, total_cents, created_at
FROM orders
WHERE (created_at, id) < ('2026-08-30T14:22:07Z', 'ord_8821')
ORDER BY created_at DESC, id DESC
LIMIT 25;

สังเกตการเปรียบเทียบสองคอลัมน์ created_at เพียงอย่างเดียวไม่ซ้ำกัน; คำสั่งซื้อสองรายการอาจเกิดขึ้นในมิลลิวินาทีเดียวกัน และคีย์การจัดเรียงที่ไม่ซ้ำกันหมายความว่าแถวอาจถูกข้ามหรือซ้ำซ้อนกันที่ขอบหน้า การเพิ่ม id เป็นตัวตัดสินเมื่อค่าเท่ากันจะทำให้การจัดเรียงสมบูรณ์และการแบ่งหน้าแม่นยำ ด้วยดัชนีรวมบน (created_at, id) ฐานข้อมูลจะค้นหาตรงไปยังขอบเขตและอ่าน 25 รายการ หน้าที่ 1 และหน้าที่ 60,000 มีค่าใช้จ่ายเท่ากัน

อย่างไรก็ตาม API ไม่ควรเปิดเผยค่าดิบเหล่านั้น การใช้งานจริงจะเข้ารหัสคีย์การจัดเรียงเป็นโทเค็นที่ไม่โปร่งใส ซึ่งมักจะเป็น base64:

GET /v1/orders?limit=25&cursor=eyJjcmVhdGVkX2F0IjoiMjAyNi0wOC0zMFQxNDoyMjowN1oiLCJpZCI6Im9yZF84ODIxIn0

ความทึบแสงเป็นเรื่องของการตัดสินใจออกแบบ ไม่ใช่การทำให้เข้าใจยากเพื่อตัวมันเอง ไคลเอนต์ที่ไม่สามารถแยกวิเคราะห์ cursor จะไม่สามารถสร้าง URL ได้ด้วยตนเอง ซึ่งทำให้คุณมีอิสระในการเปลี่ยนคีย์การจัดเรียง เพิ่มคำแนะนำในการแบ่งส่วน หรือเปลี่ยนกลไกการจัดเก็บข้อมูลได้โดยไม่ทำให้ระบบของใครพัง ข้อตกลงจึงกลายเป็น “ส่งคืนสิ่งที่เราให้คุณไป” ไม่มีอะไรมากไปกว่านั้น

ข้อแลกเปลี่ยนคือ: ไม่มีหน้า 47 Cursor รู้แค่ “หลังจากแถวนี้” เท่านั้น ดังนั้นไคลเอนต์จะเดินหน้าไป (และถอยหลังได้ หากคุณมี previous-cursor) ทีละหน้าเท่านั้น จำนวนรวมทั้งหมดก็ไม่ได้มาฟรีเช่นกัน; การนับเป็นคิวรีแยกต่างหาก สำหรับการออกแบบที่ชุดข้อมูลมีขนาดใหญ่มาก คู่มือการออกแบบการแบ่งหน้า API สำหรับข้อมูลหลายล้านรายการ ของเราครอบคลุมด้านการขยายขนาดได้ลึกซึ้งยิ่งขึ้น

ข้อดีข้อเสียโดยสรุป

มิติ การแบ่งหน้าแบบ Offset การแบ่งหน้าแบบ Cursor-based
ข้ามไปยังหน้าใดก็ได้ ได้, หมายเลขหน้าใดก็ได้ ไม่ได้, ต้องเดินหน้าไปทีละหน้าเท่านั้น
จำนวนรวม / จำนวนหน้า ง่ายต่อการรวม ต้องคิวรีเพื่อนับจำนวนแยกต่างหาก
ประสิทธิภาพในการเรียกหน้าลึก O(n), ประสิทธิภาพลดลงตามความลึก O(1) ต่อหน้าในทุกระดับความลึก
ความเสถียรภายใต้การเขียนข้อมูล เลื่อนไปมา: ข้อมูลซ้ำและช่องว่าง เสถียร, ยึดติดกับแถว
ค่าใช้จ่ายในการพัฒนา ง่ายมาก ปานกลาง: การเข้ารหัส, ตัวตัดสินเมื่อค่าเท่ากัน, การออกแบบดัชนี
ข้อกำหนดในการจัดเรียง ORDER BY ใดก็ได้ ต้องใช้คีย์การจัดเรียงที่ไม่ซ้ำกันและมีดัชนี
การแคช URL หน้า ง่าย, URL สามารถคาดเดาได้ ยากกว่า, cursors เปลี่ยนแปลงไปตามการเรียกแต่ละครั้ง
ความซับซ้อนของไคลเอนต์ ต่ำ ต่ำ, หากโครงสร้างตอบกลับชัดเจน

มีจุดที่ละเอียดอ่อนในตารางนั้นที่ควรเน้นย้ำ: การแบ่งหน้าแบบ Cursor ต้องการการจัดเรียงที่กำหนดได้ หากปลายทางของคุณอนุญาตให้ไคลเอนต์จัดเรียงตามคอลัมน์ที่เปลี่ยนแปลงได้และไม่ซ้ำกัน เช่น status ตรรกะของ Keyset จะกลายเป็นเรื่องที่ยุ่งยากอย่างรวดเร็ว Offset ทนทานต่อการจัดเรียงที่หละหลวม แต่ Cursor จะลงโทษมัน

คุณควรเลือกแบบไหน?

จับคู่รูปแบบให้เข้ากับวิธีการใช้ข้อมูล

ตารางผู้ดูแลระบบและแดชบอร์ด: Offset เครื่องมือภายในที่มีข้อมูลไม่กี่พันแถว ผู้ใช้คลิกหมายเลขหน้า และมีจำนวน “1,848 ผลลัพธ์” ที่มองเห็นได้ การเลื่อนของหน้าไม่สำคัญ ความลึกยังคงตื้น และการข้ามไปยังหน้าเป็นคุณสมบัติที่มีประโยชน์ Offset ได้เปรียบในเรื่องค่าใช้จ่ายในการพัฒนา

ฟีดแบบเลื่อนไม่สิ้นสุด (Infinite scroll feeds): Cursor ไม่มีใครข้ามไปยังหน้า 47 ของฟีด ผู้ใช้มักจะโหลด “เพิ่มเติม” เท่านั้น การเขียนข้อมูลเกิดขึ้นตลอดเวลา และข้อมูลซ้ำซ้อนสามารถมองเห็นได้และน่าอับอาย นี่คือกรณีตัวอย่างของการใช้ Cursor

Public API: Cursor คุณไม่สามารถควบคุมผู้ใช้งานของคุณได้ ใครบางคนจะเขียนลูปเพื่อเรียกดูทุกหน้า และด้วย Offset หน้าที่ลึกๆ จะกลายเป็นปัญหาของคุณตอนตี 3 Cursor ช่วยให้ทุกหน้ามีค่าใช้จ่ายต่ำ และช่วยให้คุณสามารถพัฒนาโครงสร้างภายในเบื้องหลังโทเค็นที่ไม่โปร่งใสได้ คู่มือการแบ่งหน้า REST API ของเราครอบคลุมรายละเอียดเกี่ยวกับ URL และข้อกำหนดในส่วนหัว

การส่งออกและงานซิงค์: Cursor งานแบตช์ที่ดึงคำสั่งซื้อ 2 ล้านรายการทั้งหมดต้องการการรับประกันสองประการ: ไม่มีแถวใดหายไปแม้จะมีการเขียนพร้อมกัน และมีค่าใช้จ่ายคงที่ต่อหน้า Offset ไม่มีคุณสมบัติทั้งสองประการนี้ Cursor ยังให้จุดดำเนินการต่อฟรีเมื่องานหยุดทำงานที่แถว 1.4 ล้าน

กฎง่ายๆ ที่ซื่อสัตย์: Offset สำหรับอินเทอร์เฟซขนาดเล็ก, ที่มนุษย์เรียกดู, และเน้นการนับจำนวน; Cursor สำหรับสิ่งใดก็ตามที่มีขนาดใหญ่, มีการเปลี่ยนแปลงตลอดเวลา, หรือเป็นสาธารณะ

API จริงจัดการกับเรื่องนี้อย่างไร

Stripe ใช้การแบ่งหน้าแบบ Cursor ทั้งหมด ปลายทางรายการทุกรายการยอมรับ starting_after (รหัสออบเจกต์) และ limit และการตอบกลับจะรวม has_more ในการดึงหน้าถัดไปของรายการค่าใช้จ่าย คุณจะส่งรหัสของค่าใช้จ่ายล่าสุดที่คุณได้รับ เอกสารการแบ่งหน้าของ Stripe แสดงรูปแบบนี้; โปรดทราบว่าไม่มีการนับจำนวนรวมที่ใดเลย ซึ่งเป็นการละเว้นโดยเจตนาเมื่อพิจารณาจากปริมาณการเขียนข้อมูลของพวกเขา

REST API ของ GitHub ยังคงเปิดเผย page และ per_page บนปลายทางส่วนใหญ่ พร้อมด้วยส่วนหัว Link ที่ชี้ไปยังหน้าถัดไปและหน้าสุดท้าย แต่ควรอ่าน เอกสารการแบ่งหน้าของ GitHub อย่างละเอียด: พวกเขาสั่งให้ไคลเอนต์ทำตามส่วนหัว Link อย่างเคร่งครัด แทนที่จะสร้าง URL ของหน้าเอง และปลายทางใหม่ๆ ก็ได้เปลี่ยนไปใช้ Cursor แล้ว เนื่องจากปัญหาการเรียกหน้าลึกๆ ด้วย Offset ในคลังเก็บข้อมูลขนาดใหญ่มันสร้างภาระอย่างมาก

Slack ได้ย้าย Web API ของตนไปใช้การแบ่งหน้าแบบ Cursor และตอนนี้ระบุว่าเป็นแนวทางที่เมธอดใหม่ๆ ทั้งหมดใช้ เมธอดเช่น conversations.history จะส่งคืน response_metadata.next_cursor และสตริง cursor ที่ว่างเปล่าหมายความว่าคุณมาถึงจุดสิ้นสุดแล้ว ดังที่อธิบายไว้ใน เอกสารการแบ่งหน้าของ Slack

API ที่มีการเข้าชมสูงสามแห่ง และทิศทางของการเดินทางก็เป็นไปในทางเดียวกัน: ไปสู่การใช้ Cursor

การออกแบบโครงสร้างการตอบกลับ

ความสำเร็จของ Cursor API ขึ้นอยู่กับโครงสร้างการตอบกลับของมัน ทำให้มันเรียบง่ายและคาดเดาได้:

{
  "data": [
    {
      "id": "ord_8846",
      "customer_id": "cus_2201",
      "total_cents": 12900,
      "created_at": "2026-08-30T16:01:44Z"
    }
  ],
  "has_more": true,
  "next_cursor": "eyJjcmVhdGVkX2F0IjoiMjAyNi0wOC0zMFQxNjowMTo0NFoiLCJpZCI6Im9yZF84ODQ2In0"
}

สี่กฎที่ทำให้มันแข็งแกร่ง:

การทดสอบทั้งสองรูปแบบใน Apidog

ข้อผิดพลาดในการแบ่งหน้าซ่อนอยู่ที่ขอบเขต: หน้าสุดท้าย, หน้าว่าง, cursor ที่แถวหลักถูกลบ การคลิกด้วยมือจะไม่สามารถตรวจจับได้ แต่สถานการณ์การทดสอบแบบลูกโซ่จะทำได้ และนี่คือจุดที่ Apidog เข้ามามีบทบาทในเวิร์กโฟลว์

สำหรับปลายทาง Cursor ให้สร้างสถานการณ์การทดสอบที่มีสองขั้นตอน:

  1. เรียกใช้ปลายทางและดึง cursor เพิ่ม post-processor ในคำขอแรกด้วย JSONPath $.next_cursor และจัดเก็บไว้ในตัวแปรเช่น nextCursor Apidog ช่วยให้คุณคัดลอก JSONPath ได้โดยตรงจากแผงการตอบกลับ; คำแนะนำแบบเต็มอยู่ใน วิธีการตั้งค่า assertions และดึงตัวแปรด้วย JSONPath
  2. วนซ้ำคำขอหน้าถัดไป ห่อคำขอที่สองในขั้นตอน ForEach หรือ loop ส่ง {{nextCursor}} เป็นพารามิเตอร์ cursor ดึง $.next_cursor ซ้ำทุกรอบ และออกเมื่อ has_more เป็น false ตรวจสอบทุกครั้งว่าไม่มี id ซ้ำจากหน้าก่อนหน้า และขนาดหน้าไม่เกิน limit

สำหรับปลายทาง Offset โครงสร้างเดียวกันนี้ใช้ได้กับตัวแปรนับ: เพิ่ม page ตรวจสอบว่าความยาวของ data เท่ากับ per_page จนถึงหน้าสุดท้าย และตรวจสอบว่า total ยังคงสอดคล้องกันตลอดการเรียกดู

จากนั้นเพิ่มกรณีขอบ (edge cases) เป็นขั้นตอนของตัวเอง โดยแต่ละขั้นตอนมีการยืนยันที่ชัดเจน:

เมื่อสถานการณ์ผ่านการทดสอบในเครื่องแล้ว ให้รันใน CI ทุกครั้งที่มีการผสานโค้ด ดาวน์โหลด Apidog ฟรี แล้วคุณจะสามารถมีสถานการณ์การเรียกดู cursor แบบเต็มรูปแบบ พร้อมลูปและการยืนยันรวมอยู่ด้วย ใช้งานได้ภายในเวลาไม่ถึงครึ่งชั่วโมง

คำถามที่พบบ่อย

การแบ่งหน้าแบบ Cursor ดีกว่าเสมอไปหรือไม่?

ไม่ Offset เหมาะสมกว่าเมื่อผู้ใช้ต้องการหมายเลขหน้า, ยอดรวม, และการเข้าถึงแบบสุ่มบนชุดข้อมูลขนาดปานกลาง ซึ่งเป็นลักษณะของเครื่องมือผู้ดูแลระบบภายในส่วนใหญ่ Cursor ดีกว่าเมื่อชุดข้อมูลมีขนาดใหญ่, มีการเขียนข้อมูลบ่อยครั้ง, หรือ API เป็นสาธารณะ จุดที่ล้มเหลวคือการใช้ Offset เป็นค่าเริ่มต้นสำหรับปลายทางรายการสาธารณะและค้นพบค่าใช้จ่าย O(n) หลังจากเปิดใช้งาน

ฉันจะนับจำนวนรวมทั้งหมดด้วยการแบ่งหน้าแบบ Cursor ได้อย่างไร?

รัน SELECT COUNT(*) แยกต่างหากด้วยตัวกรองเดียวกัน ไม่ว่าจะเป็นปลายทางที่แตกต่างกัน หรือพารามิเตอร์คิวรีแบบเลือกใช้ เช่น include_count=true แคชอย่างรุนแรง; การนับจำนวนโดยประมาณที่อัปเดตทุกนาทีก็เพียงพอสำหรับ UI เกือบทั้งหมด Stripe ข้ามการนับรวมทั้งหมดไปเลย ซึ่งบอกให้รู้ว่าบ่อยครั้งแค่ไหนที่ไคลเอนต์ต้องการมันจริงๆ

ฉันสามารถเสนอการแบ่งหน้าทั้งสองรูปแบบในปลายทางเดียวได้หรือไม่?

คุณทำได้ และ GitHub ก็ทำอย่างมีประสิทธิภาพในช่วงเปลี่ยนผ่าน แต่ควรหลีกเลี่ยงใน API ใหม่ๆ สองรูปแบบหมายถึงสองชุดของกรณีขอบ, สองเมทริกซ์การทดสอบ, และความสับสนของไคลเอนต์ว่าจะใช้อันไหนดี เลือกเพียงหนึ่งรูปแบบต่อปลายทาง หากคุณกำลังออกแบบข้อตกลงตั้งแต่เริ่มต้น รูปแบบใน คู่มือการแบ่งหน้า REST API ของเราจะช่วยให้การตั้งชื่อพารามิเตอร์มีความสอดคล้องกันทั่วทั้งอินเทอร์เฟซของคุณ

จะเกิดอะไรขึ้นหากแถวหลักของ Cursor ถูกลบไป?

ด้วย Keyset Pagination จะไม่มีอะไรพัง การเปรียบเทียบ WHERE (created_at, id) < (?, ?) ไม่จำเป็นต้องให้แถวหลักมีอยู่จริง มันจะค้นหาไปยังตำแหน่งขอบเขตและดำเนินต่อไป นี่เป็นข้อได้เปรียบที่แท้จริงเหนือการออกแบบ “cursor เป็นการค้นหาแถว” และเป็นกรณีขอบที่คุ้มค่าแก่การยืนยันในสถานการณ์ทดสอบ Apidog ของคุณ ก่อนที่ผู้ใช้งานจะพบมันเอง

ฝึกการออกแบบ API แบบ Design-first ใน Apidog

ค้นพบวิธีที่ง่ายขึ้นในการสร้างและใช้ API