ข้ามไปยังเนื้อหาหลัก
เวอร์ชัน: ล่าสุด

การแบ่งหน้า

นำทางชุดผลลัพธ์ขนาดใหญ่อย่างมีประสิทธิภาพด้วยการแบ่งหน้า API ของ Omise เรียนรู้วิธีใช้พารามิเตอร์ limit และ offset เพื่อดึงข้อมูลเป็นกลุ่มที่จัดการได้

ภาพรวม

endpoint ของ Omise API จำนวนมากส่งคืนรายการของทรัพยากร (การเรียกเก็บเงิน ลูกค้า การโอนเงิน ฯลฯ) เพื่อให้การตอบกลับรวดเร็วและจัดการได้ง่าย endpoint เหล่านี้จะส่งคืนผลลัพธ์แบบแบ่งหน้า คุณสามารถควบคุมจำนวนรายการที่จะดึงข้อมูลต่อคำขอและหน้าที่จะเรียกข้อมูล

เริ่มต้นอย่างรวดเร็ว
  • ใช้ limit เพื่อควบคุมจำนวนรายการต่อหน้า (ค่าเริ่มต้น: 20, สูงสุด: 100)
  • ใช้ offset เพื่อข้ามรายการและนำทางหน้า
  • ตรวจสอบ total เพื่อทราบจำนวนรายการที่มีอยู่
  • การตอบกลับแบบรายการทั้งหมดมีโครงสร้างเดียวกัน

พารามิเตอร์การแบ่งหน้า

limit

ประเภท: Integer ค่าเริ่มต้น: 20 ช่วง: 1-100 วัตถุประสงค์: จำนวนรายการที่จะส่งคืนต่อคำขอ

# รับ 50 การเรียกเก็บเงินต่อคำขอ
curl https://api.omise.co/charges?limit=50 \
-u skey_test_5xuy4w91xqz7d1w9u0t:

offset

ประเภท: Integer ค่าเริ่มต้น: 0 วัตถุประสงค์: จำนวนรายการที่จะข้ามก่อนเริ่มส่งคืนผลลัพธ์

# ข้าม 20 การเรียกเก็บเงินแรก ส่งคืน 20 รายการถัดไป
curl https://api.omise.co/charges?offset=20&limit=20 \
-u skey_test_5xuy4w91xqz7d1w9u0t:

ตัวอย่างรวม

# รับรายการ 41-60 (หน้า 3 พร้อม 20 รายการต่อหน้า)
curl https://api.omise.co/charges?offset=40&limit=20 \
-u skey_test_5xuy4w91xqz7d1w9u0t:

รูปแบบการตอบกลับรายการ

endpoint ที่มีการแบ่งหน้าทั้งหมดส่งคืนโครงสร้างรายการที่สอดคล้องกัน:

{
"object": "list",
"data": [
{
"object": "charge",
"id": "chrg_test_5xuy4w91xqz7d1w9u0t",
"amount": 100000,
...
},
{
"object": "charge",
"id": "chrg_test_5xuy4w91xqz7d1w9u0a",
"amount": 50000,
...
}
],
"limit": 20,
"offset": 0,
"total": 142,
"from": "2025-01-01T00:00:00Z",
"to": "2025-02-07T23:59:59Z",
"order": "chronological",
"location": "/charges"
}

ฟิลด์ออบเจ็กต์รายการ

ฟิลด์ประเภทคำอธิบาย
objectstringเป็น "list" เสมอสำหรับการตอบกลับแบบแบ่งหน้า
dataarrayอาร์เรย์ของออบเจ็กต์ทรัพยากร (การเรียกเก็บเงิน ลูกค้า ฯลฯ)
limitintegerจำนวนรายการต่อหน้า (จากคำขอ)
offsetintegerจำนวนรายการที่ข้าม (จากคำขอ)
totalintegerจำนวนรายการทั้งหมดในทุกหน้า
fromstring (ISO 8601)วันที่เริ่มต้นของช่วงเวลาคิวรี (ตัวเลือก)
tostring (ISO 8601)วันที่สิ้นสุดของช่วงเวลาคิวรี (ตัวเลือก)
orderstringลำดับการเรียง: "chronological" หรือ "reverse_chronological"
locationstringเส้นทาง endpoint ของ API

endpoint ที่มีการแบ่งหน้า

endpoint ต่อไปนี้รองรับการแบ่งหน้า:

ทรัพยากรหลัก

Endpointลำดับเริ่มต้นคำอธิบาย
GET /chargesย้อนเวลาตามลำดับรายการการเรียกเก็บเงินทั้งหมด
GET /customersย้อนเวลาตามลำดับรายการลูกค้าทั้งหมด
GET /transfersย้อนเวลาตามลำดับรายการการโอนเงินทั้งหมด
GET /refundsย้อนเวลาตามลำดับรายการการคืนเงินทั้งหมด
GET /transactionsย้อนเวลาตามลำดับรายการธุรกรรมทั้งหมด
GET /disputesย้อนเวลาตามลำดับรายการข้อพิพาททั้งหมด
GET /recipientsย้อนเวลาตามลำดับรายการผู้รับทั้งหมด
GET /eventsย้อนเวลาตามลำดับรายการเหตุการณ์ทั้งหมด
GET /schedulesย้อนเวลาตามลำดับรายการกำหนดการทั้งหมด
GET /linksย้อนเวลาตามลำดับรายการลิงก์การชำระเงินทั้งหมด

ทรัพยากรที่ซ้อนกัน

Endpointคำอธิบาย
GET /customers/:id/cardsรายการบัตรสำหรับลูกค้า
GET /charges/:id/refundsรายการการคืนเงินสำหรับการเรียกเก็บเงิน
GET /customers/:id/chargesรายการการเรียกเก็บเงินสำหรับลูกค้า

ตัวอย่างการแบ่งหน้าพื้นฐาน

การแบ่งหน้าเริ่มต้น

รับ 20 รายการแรก (พฤติกรรมเริ่มต้น):

curl https://api.omise.co/charges \
-u skey_test_5xuy4w91xqz7d1w9u0t:

การตอบกลับ:

{
"object": "list",
"data": [...],
"limit": 20,
"offset": 0,
"total": 142
}

ขนาดหน้าแบบกำหนดเอง

รับ 50 รายการต่อหน้า:

curl https://api.omise.co/charges?limit=50 \
-u skey_test_5xuy4w91xqz7d1w9u0t:

ไปที่หน้า 2

ข้าม 20 รายการแรก รับ 20 รายการถัดไป:

curl https://api.omise.co/charges?offset=20&limit=20 \
-u skey_test_5xuy4w91xqz7d1w9u0t:

ไปที่หน้า 3

ข้าม 40 รายการแรก รับ 20 รายการถัดไป:

curl https://api.omise.co/charges?offset=40&limit=20 \
-u skey_test_5xuy4w91xqz7d1w9u0t:

รับรายการสูงสุด

รับ 100 รายการ (สูงสุดที่อนุญาต):

curl https://api.omise.co/charges?limit=100 \
-u skey_test_5xuy4w91xqz7d1w9u0t:

การแบ่งหน้า Patterns

รูปแบบ 1: วนซ้ำทุกหน้า

ดึงข้อมูลรายการทั้งหมดโดยวนซ้ำผ่านหน้า:

# Ruby - ดึงข้อมูลการเรียกเก็บเงินทั้งหมด
require 'omise'

Omise.api_key = ENV['OMISE_SECRET_KEY']

all_charges = []
offset = 0
limit = 100

loop do
page = Omise::Charge.list(limit: limit, offset: offset)

all_charges.concat(page.data)

# ตรวจสอบว่าเราได้ดึงข้อมูลรายการทั้งหมดแล้ว
break if offset + page.data.length >= page.total

offset += limit
end

puts "ดึงข้อมูล #{all_charges.length} การเรียกเก็บเงินทั้งหมด"

รูปแบบ 2: คำนวณจำนวนหน้าทั้งหมด

กำหนดว่ามีหน้ากี่หน้า:

# Python - คำนวณจำนวนหน้าทั้งหมด
import omise
import math

omise.api_secret = os.environ['OMISE_SECRET_KEY']

# รับหน้าแรกเพื่อรับจำนวนทั้งหมด
first_page = omise.Charge.list(limit=20, offset=0)
total_items = first_page['total']
items_per_page = 20

total_pages = math.ceil(total_items / items_per_page)

print(f"รายการทั้งหมด: {total_items}")
print(f"หน้าทั้งหมด: {total_pages}")

รูปแบบ 3: การนำทางหน้า UI

สร้างการนำทางหน้าสำหรับ UI:

// Node.js - ตรรกะการนำทางหน้า
const omise = require('omise')({
secretKey: process.env.OMISE_SECRET_KEY
});

async function getChargesPage(pageNumber, itemsPerPage = 20) {
const offset = (pageNumber - 1) * itemsPerPage;

const result = await omise.charges.list({
limit: itemsPerPage,
offset: offset
});

const totalPages = Math.ceil(result.total / itemsPerPage);

return {
charges: result.data,
pagination: {
currentPage: pageNumber,
totalPages: totalPages,
totalItems: result.total,
itemsPerPage: itemsPerPage,
hasNextPage: pageNumber < totalPages,
hasPrevPage: pageNumber > 1
}
};
}

// การใช้งาน: รับหน้า 3
const page3 = await getChargesPage(3, 20);
console.log(page3.pagination);
// {
// currentPage: 3,
// totalPages: 8,
// totalItems: 142,
// itemsPerPage: 20,
// hasNextPage: true,
// hasPrevPage: true
// }

รูปแบบ 4: การวนซ้ำแบบเคอร์เซอร์

วนซ้ำผ่านผลลัพธ์ทั้งหมดอย่างมีประสิทธิภาพ:

<?php
// PHP - วนซ้ำการเรียกเก็บเงินทั้งหมด

require_once 'vendor/autoload.php';

define('OMISE_SECRET_KEY', getenv('OMISE_SECRET_KEY'));

function getAllCharges($limit = 100) {
$allCharges = [];
$offset = 0;

do {
$page = OmiseCharge::retrieve([
'limit' => $limit,
'offset' => $offset
]);

$allCharges = array_merge($allCharges, $page['data']);

$offset += count($page['data']);
$hasMore = $offset < $page['total'];

} while ($hasMore);

return $allCharges;
}

$charges = getAllCharges();
echo "ดึงข้อมูล " . count($charges) . " การเรียกเก็บเงิน\n";

รูปแบบ 5: การโหลดแบบเกียจคร้าน

โหลดรายการเพิ่มเติมตามความต้องการ (การเลื่อนแบบไม่มีที่สิ้นสุด):

// JavaScript - การโหลดแบบเกียจคร้านสำหรับ UI
class ChargeLoader {
constructor(itemsPerPage = 20) {
this.itemsPerPage = itemsPerPage;
this.offset = 0;
this.allCharges = [];
this.hasMore = true;
this.total = null;
}

async loadMore() {
if (!this.hasMore) {
return { charges: [], hasMore: false };
}

const response = await fetch('/api/charges', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
limit: this.itemsPerPage,
offset: this.offset
})
});

const result = await response.json();

this.allCharges.push(...result.data);
this.offset += result.data.length;
this.total = result.total;
this.hasMore = this.offset < this.total;

return {
charges: result.data,
hasMore: this.hasMore,
total: this.total,
loaded: this.offset
};
}

reset() {
this.offset = 0;
this.allCharges = [];
this.hasMore = true;
this.total = null;
}
}

// การใช้งาน
const loader = new ChargeLoader(20);

// โหลดหน้าแรก
const page1 = await loader.loadMore();
console.log(`โหลด ${page1.charges.length} การเรียกเก็บเงิน`);

// โหลดหน้าที่สอง (ผู้ใช้เลื่อนลง)
const page2 = await loader.loadMore();
console.log(`โหลด ${page2.charges.length} การเรียกเก็บเงินเพิ่มเติม`);

รูปแบบ 6: การแบ่งหน้าแบบย้อนกลับ (ใหม่ที่สุดก่อน)

รับรายการล่าสุดก่อน:

// Go - รับการเรียกเก็บเงินล่าสุดก่อน
package main

import (
"fmt"
"github.com/omise/omise-go"
"github.com/omise/omise-go/operations"
)

func getRecentCharges(limit int) ([]*omise.Charge, error) {
client, _ := omise.NewClient(
os.Getenv("OMISE_PUBLIC_KEY"),
os.Getenv("OMISE_SECRET_KEY"),
)

// ลำดับเริ่มต้นคือ reverse_chronological (ใหม่ที่สุดก่อน)
charges, err := client.Charges().List(&operations.ListCharges{
Limit: limit,
Offset: 0,
})

if err != nil {
return nil, err
}

return charges.Data, nil
}

func main() {
// รับ 50 การเรียกเก็บเงินล่าสุด
charges, _ := getRecentCharges(50)

for i, charge := range charges {
fmt.Printf("%d. %s - %d %s\n",
i+1,
charge.ID,
charge.Amount,
charge.Currency,
)
}
}

เทคนิคการแบ่งหน้าขั้นสูง

การรวมกับตัวกรอง

การแบ่งหน้าทำงานกับตัวกรองวันที่และพารามิเตอร์อื่นๆ:

# รับการเรียกเก็บเงินจากมกราคม 2025 หน้า 2
curl "https://api.omise.co/charges?from=2025-01-01T00:00:00Z&to=2025-01-31T23:59:59Z&limit=20&offset=20" \
-u skey_test_5xuy4w91xqz7d1w9u0t:
# Ruby - ตัวกรอง + การแบ่งหน้า
charges = Omise::Charge.list(
from: '2025-01-01T00:00:00Z',
to: '2025-01-31T23:59:59Z',
limit: 50,
offset: 0
)

การดึงข้อมูลชุดข้อมูลขนาดใหญ่อย่างมีประสิทธิภาพ

สำหรับชุดข้อมูลขนาดใหญ่มาก ใช้ขนาดหน้าที่ใหญ่ขึ้น:

# Python - การดึงข้อมูลจำนวนมากอย่างมีประสิทธิภาพ
import omise

omise.api_secret = os.environ['OMISE_SECRET_KEY']

def fetch_all_charges_efficiently():
all_charges = []
offset = 0
limit = 100 # สูงสุดที่อนุญาต

while True:
page = omise.Charge.list(limit=limit, offset=offset)

if not page['data']:
break

all_charges.extend(page['data'])

# ตรวจสอบว่าเราได้รายการทั้งหมดแล้ว
if offset + len(page['data']) >= page['total']:
break

offset += limit

# ตัวเลือก: การจำกัดอัตรา
time.sleep(0.1)

return all_charges

charges = fetch_all_charges_efficiently()
print(f"ดึงข้อมูล {len(charges)} การเรียกเก็บเงิน")

การติดตามความคืบหน้า

แสดงความคืบหน้าเมื่อดึงข้อมูลชุดข้อมูลขนาดใหญ่:

// Node.js - การติดตามความคืบหน้า
async function fetchAllChargesWithProgress(onProgress) {
const limit = 100;
let offset = 0;
let allCharges = [];

// รับหน้าแรกเพื่อทราบจำนวนทั้งหมด
const firstPage = await omise.charges.list({ limit, offset });
const total = firstPage.total;

allCharges.push(...firstPage.data);
offset += firstPage.data.length;

onProgress({
loaded: offset,
total: total,
percentage: Math.round((offset / total) * 100)
});

// ดึงข้อมูลหน้าที่เหลือ
while (offset < total) {
const page = await omise.charges.list({ limit, offset });

allCharges.push(...page.data);
offset += page.data.length;

onProgress({
loaded: offset,
total: total,
percentage: Math.round((offset / total) * 100)
});
}

return allCharges;
}

// การใช้งาน
const charges = await fetchAllChargesWithProgress((progress) => {
console.log(`กำลังโหลด: ${progress.percentage}% (${progress.loaded}/${progress.total})`);
});

การดึงข้อมูลหน้าแบบขนาน

ดึงข้อมูลหลายหน้าพร้อมกัน (ใช้ด้วยความระมัดระวังเนื่องจากขีดจำกัดอัตรา):

// Node.js - การดึงข้อมูลแบบขนาน (ขั้นสูง)
async function fetchMultiplePagesParallel(startPage, endPage, itemsPerPage = 20) {
const pageNumbers = Array.from(
{ length: endPage - startPage + 1 },
(_, i) => i + startPage
);

const pagePromises = pageNumbers.map(async (pageNum) => {
const offset = (pageNum - 1) * itemsPerPage;
return omise.charges.list({ limit: itemsPerPage, offset });
});

const pages = await Promise.all(pagePromises);

// รวมทุกหน้าเป็นอาร์เรย์เดียว
const allCharges = pages.flatMap(page => page.data);

return {
charges: allCharges,
total: pages[0].total
};
}

// ดึงข้อมูลหน้า 1-5 แบบขนาน
const result = await fetchMultiplePagesParallel(1, 5, 20);
console.log(`ดึงข้อมูล ${result.charges.length} การเรียกเก็บเงิน`);
การจำกัดอัตรา

คำขอแบบขนานนับรวมในขีดจำกัดอัตราของคุณ ใช้เทคนิคนี้อย่างระมัดระวังและพิจารณาใช้งานความล่าช้าระหว่างคำขอ


การจัดการกรณีขอบเขต

ผลลัพธ์ว่างเปล่า

เมื่อไม่มีรายการที่ตรงกับคิวรี:

{
"object": "list",
"data": [],
"limit": 20,
"offset": 0,
"total": 0,
"location": "/charges"
}
// ตรวจสอบผลลัพธ์ว่างเปล่า
const charges = await omise.charges.list({ limit: 20 });

if (charges.data.length === 0) {
console.log('ไม่พบการเรียกเก็บเงิน');
} else {
console.log(`พบ ${charges.data.length} การเรียกเก็บเงิน`);
}

Offset เกินจำนวนทั้งหมด

การขอ offset เกินรายการที่มีอยู่:

# จำนวนทั้งหมดคือ 50 แต่ร้องขอ offset 100
curl "https://api.omise.co/charges?offset=100&limit=20" \
-u skey_test_...:

การตอบกลับ:

{
"object": "list",
"data": [],
"limit": 20,
"offset": 100,
"total": 50
}

ผลลัพธ์บางส่วนของหน้าสุดท้าย

หน้าสุดท้ายอาจมีรายการน้อยกว่า limit:

# จำนวนทั้งหมดคือ 145 ร้องขอรายการ 141-160
curl "https://api.omise.co/charges?offset=140&limit=20" \
-u skey_test_...:

การตอบกลับ:

{
"object": "list",
"data": [
{ "object": "charge", "id": "chrg_141" },
{ "object": "charge", "id": "chrg_142" },
{ "object": "charge", "id": "chrg_143" },
{ "object": "charge", "id": "chrg_144" },
{ "object": "charge", "id": "chrg_145" }
],
"limit": 20,
"offset": 140,
"total": 145
}
// ตรวจจับหน้าสุดท้าย
const page = await omise.charges.list({ offset: 140, limit: 20 });

const isLastPage = page.offset + page.data.length >= page.total;
console.log(`เป็นหน้าสุดท้าย: ${isLastPage}`); // true

การเปลี่ยนแปลงรวมแบบไดนามิก

จำนวน total สามารถเปลี่ยนแปลงระหว่างคำขอหากมีการสร้างรายการใหม่:

// คำขอแรก
const page1 = await omise.charges.list({ limit: 20, offset: 0 });
console.log(`จำนวนทั้งหมด: ${page1.total}`); // 100

// มีการสร้างการเรียกเก็บเงินใหม่...

// คำขอที่สอง
const page2 = await omise.charges.list({ limit: 20, offset: 20 });
console.log(`จำนวนทั้งหมด: ${page2.total}`); // 105 (เปลี่ยนแปลง!)

// จัดการสิ่งนี้โดยตรวจสอบจำนวนทั้งหมดในแต่ละคำขอ

แนวทางปฏิบัติที่ดีที่สุด

1. ใช้ขนาดหน้าที่เหมาะสม

// ✅ ดี - เลือกขนาดตามกรณีการใช้งาน

// สำหรับการแสดงผล UI (อย่าให้ผู้ใช้ครอบงำ)
const charges = await omise.charges.list({ limit: 20 });

// สำหรับการประมวลผลจำนวนมาก (เพิ่มประสิทธิภาพสูงสุด)
const chargesForExport = await omise.charges.list({ limit: 100 });

// สำหรับการอัปเดตแบบเรียลไทม์ (ลดเวลาแฝงขั้นต่ำ)
const recentCharges = await omise.charges.list({ limit: 10 });

2. แคชผลลัพธ์เมื่อเป็นไปได้

# ✅ ดี - แคชผลลัพธ์แบบแบ่งหน้า
require 'redis'

redis = Redis.new

def get_charges_page(page_num, cache_ttl = 300)
cache_key = "charges:page:#{page_num}"

# ลองแคชก่อน
cached = redis.get(cache_key)
return JSON.parse(cached) if cached

# ดึงข้อมูลจาก API
offset = (page_num - 1) * 20
charges = Omise::Charge.list(limit: 20, offset: offset)

# แคชเป็นเวลา 5 นาที
redis.setex(cache_key, cache_ttl, charges.to_json)

charges
end

3. จัดการข้อผิดพลาดการแบ่งหน้า

# ✅ ดี - จัดการข้อผิดพลาดการแบ่งหน้า
import omise

def safe_list_charges(offset=0, limit=20, max_retries=3):
for attempt in range(max_retries):
try:
return omise.Charge.list(offset=offset, limit=limit)

except omise.errors.BaseError as e:
if attempt == max_retries - 1:
raise

if e.http_status >= 500:
# ข้อผิดพลาดเซิร์ฟเวอร์ - ลองใหม่
time.sleep(2 ** attempt)
continue
else:
# ข้อผิดพลาดไคลเอนต์ - อย่าลองใหม่
raise

charges = safe_list_charges(offset=0, limit=50)

4. ตรวจสอบความถูกต้องของพารามิเตอร์การแบ่งหน้า

<?php
// ✅ ดี - ตรวจสอบพารามิเตอร์

function getChargesPage($pageNum, $itemsPerPage) {
// ตรวจสอบหมายเลขหน้า
if ($pageNum < 1) {
throw new InvalidArgumentException('หมายเลขหน้าต้อง >= 1');
}

// ตรวจสอบรายการต่อหน้า
if ($itemsPerPage < 1 || $itemsPerPage > 100) {
throw new InvalidArgumentException('รายการต่อหน้าต้องเป็น 1-100');
}

$offset = ($pageNum - 1) * $itemsPerPage;

return OmiseCharge::retrieve([
'limit' => $itemsPerPage,
'offset' => $offset
]);
}

5. แสดงสถานะการแบ่งหน้าให้ผู้ใช้

// ✅ ดี - UI การแบ่งหน้าที่ชัดเจน
function renderPagination(currentPage, totalPages) {
return `
<div class="pagination">
<button ${currentPage === 1 ? 'disabled' : ''}>
ก่อนหน้า
</button>

<span>หน้า ${currentPage} จาก ${totalPages}</span>

<button ${currentPage === totalPages ? 'disabled' : ''}>
ถัดไป
</button>

<span class="total-info">
แสดง ${(currentPage - 1) * 20 + 1}-${Math.min(currentPage * 20, totalItems)}
จาก ${totalItems} รายการ
</span>
</div>
`;
}

6. ปรับแต่งสำหรับชุดข้อมูลขนาดใหญ่

# ✅ ดี - สตรีมชุดข้อมูลขนาดใหญ่
def export_all_charges_to_csv
CSV.open('charges.csv', 'wb') do |csv|
csv << ['ID', 'จำนวน', 'สกุลเงิน', 'สถานะ', 'สร้างเมื่อ']

offset = 0
limit = 100

loop do
page = Omise::Charge.list(limit: limit, offset: offset)

page.data.each do |charge|
csv << [
charge.id,
charge.amount,
charge.currency,
charge.status,
charge.created_at
]
end

break if offset + page.data.length >= page.total

offset += limit

# การจำกัดอัตรา
sleep(0.5)
end
end
end

7. คำนวณหมายเลขหน้าอย่างถูกต้อง

// ✅ ดี - การคำนวณหน้าที่ถูกต้อง

function calculatePageInfo(offset, limit, total) {
const currentPage = Math.floor(offset / limit) + 1;
const totalPages = Math.ceil(total / limit);
const itemsOnPage = Math.min(limit, total - offset);

return {
currentPage,
totalPages,
itemsOnPage,
firstItemNum: offset + 1,
lastItemNum: offset + itemsOnPage,
hasNextPage: offset + limit < total,
hasPrevPage: offset > 0
};
}

// ตัวอย่าง
const info = calculatePageInfo(40, 20, 142);
console.log(info);
// {
// currentPage: 3,
// totalPages: 8,
// itemsOnPage: 20,
// firstItemNum: 41,
// lastItemNum: 60,
// hasNextPage: true,
// hasPrevPage: true
// }

ข้อพิจารณาด้านประสิทธิภาพ

ประสิทธิภาพคำขอ

รายการต่อหน้าคำขอ API สำหรับ 1000 รายการแนะนำสำหรับ
10100 คำขอการอัปเดต UI แบบเรียลไทม์
20 (เริ่มต้น)50 คำขอการแสดงผล UI ทั่วไป
5020 คำขอแดชบอร์ดผู้ดูแลระบบ
100 (สูงสุด)10 คำขอการประมวลผลจำนวนมาก การส่งออก

การจัดการหน่วยความจำ

# ✅ ดี - ประมวลผลเป็นกลุ่มเพื่อจัดการหน่วยความจำ
def process_all_charges():
offset = 0
limit = 100

while True:
# ดึงข้อมูลหน้า
page = omise.Charge.list(limit=limit, offset=offset)

if not page['data']:
break

# ประมวลผลหน้านี้
for charge in page['data']:
process_charge(charge)

# อย่าเก็บการเรียกเก็บเงินทั้งหมดในหน่วยความจำ
offset += len(page['data'])

if offset >= page['total']:
break

# ❌ ไม่ดี - โหลดทุกอย่างเข้าหน่วยความจำ
def process_all_charges_bad():
all_charges = []
offset = 0

# อาจใช้ RAM หลายกิกะไบต์สำหรับชุดข้อมูลขนาดใหญ่
while True:
page = omise.Charge.list(limit=100, offset=offset)
all_charges.extend(page['data'])
offset += 100
if offset >= page['total']:
break

for charge in all_charges:
process_charge(charge)

การตระหนักรู้เรื่องการจำกัดอัตรา

// ✅ ดี - เคารพขีดจำกัดอัตรา
async function fetchAllChargesSafely() {
const charges = [];
let offset = 0;
const limit = 100;

while (true) {
try {
const page = await omise.charges.list({ limit, offset });

charges.push(...page.data);

if (offset + page.data.length >= page.total) {
break;
}

offset += limit;

// หน่วงเล็กน้อยเพื่อหลีกเลี่ยงขีดจำกัดอัตรา
await new Promise(resolve => setTimeout(resolve, 100));

} catch (error) {
if (error.statusCode === 429) {
// ถูกจำกัดอัตรา - รอนานขึ้น
await new Promise(resolve => setTimeout(resolve, 5000));
continue;
}
throw error;
}
}

return charges;
}

การทดสอบการแบ่งหน้า

ทดสอบกรณีขอบเขต

# ทดสอบกรณีขอบเขตการแบ่งหน้า
describe 'Charge Pagination' do
it 'จัดการหน้าแรก' do
charges = Omise::Charge.list(limit: 20, offset: 0)
expect(charges.offset).to eq(0)
expect(charges.data.length).to be <= 20
end

it 'จัดการหน้าสุดท้าย' do
first_page = Omise::Charge.list(limit: 20, offset: 0)
total = first_page.total

# คำนวณ offset หน้าสุดท้าย
last_offset = (total / 20) * 20

last_page = Omise::Charge.list(limit: 20, offset: last_offset)
expect(last_page.data.length).to be <= 20
end

it 'จัดการผลลัพธ์ว่างเปล่า' do
# ตัวกรองที่ไม่ส่งคืนผลลัพธ์
charges = Omise::Charge.list(
from: '2030-01-01T00:00:00Z',
to: '2030-01-02T00:00:00Z'
)
expect(charges.data).to be_empty
expect(charges.total).to eq(0)
end

it 'จัดการ offset เกินจำนวนทั้งหมด' do
charges = Omise::Charge.list(limit: 20, offset: 999999)
expect(charges.data).to be_empty
end
end

ข้อผิดพลาดทั่วไป

❌ อย่า: ใส่ค่า Offset แบบฮาร์ดโค้ด

// ❌ ไม่ดี - สมมติข้อมูลคงที่
const page1 = await omise.charges.list({ offset: 0, limit: 20 });
const page2 = await omise.charges.list({ offset: 20, limit: 20 });
// หากมีการเพิ่ม/ลบรายการ page2 อาจมีรายการซ้ำหรือช่องว่าง
// ✅ ดี - คำนวณ offset แบบไดนามิก
let offset = 0;
const limit = 20;

const page1 = await omise.charges.list({ limit, offset });
offset += page1.data.length; // Offset แบบไดนามิก

const page2 = await omise.charges.list({ limit, offset });

❌ อย่า: ละเลยจำนวนรวม

# ❌ ไม่ดี - ไม่ตรวจสอบว่ามีหน้าเพิ่มเติมหรือไม่
offset = 0
while True:
page = omise.Charge.list(limit=20, offset=offset)
process(page['data'])
offset += 20
# วนลูปตลอดไปถ้าคุณไม่ตรวจสอบจำนวนทั้งหมด!
# ✅ ดี - ตรวจสอบจำนวนทั้งหมด
offset = 0
limit = 20

while True:
page = omise.Charge.list(limit=limit, offset=offset)
process(page['data'])

offset += len(page['data'])
if offset >= page['total']:
break

❌ อย่า: ใช้ Limit > 100

# ❌ ไม่ดี - Limit สูงเกินไป
curl "https://api.omise.co/charges?limit=500" \
-u skey_test_...:
# ข้อผิดพลาด: limit ต้อง <= 100
# ✅ ดี - ใช้สูงสุด 100
curl "https://api.omise.co/charges?limit=100" \
-u skey_test_...:

อ้างอิงอย่างรวดเร็ว

พารามิเตอร์การแบ่งหน้า

พารามิเตอร์ประเภทค่าเริ่มต้นช่วงคำอธิบาย
limitinteger201-100รายการต่อหน้า
offsetinteger00-∞รายการที่จะข้าม

ฟิลด์การตอบกลับรายการ

{
"object": "list",
"data": [...], // อาร์เรย์ของรายการ
"limit": 20, // รายการต่อหน้า
"offset": 0, // รายการที่ข้าม
"total": 142, // รายการทั้งหมด
"from": "...", // วันที่เริ่มต้น (ตัวเลือก)
"to": "...", // วันที่สิ้นสุด (ตัวเลือก)
"order": "...", // ลำดับการเรียง
"location": "..." // เส้นทาง endpoint
}

คำนวณหน้า

// หมายเลขหน้าปัจจุบัน
const currentPage = Math.floor(offset / limit) + 1;

// จำนวนหน้าทั้งหมด
const totalPages = Math.ceil(total / limit);

// มีหน้าถัดไป
const hasNextPage = offset + limit < total;

// มีหน้าก่อนหน้า
const hasPrevPage = offset > 0;

// Offset หน้าถัดไป
const nextOffset = offset + limit;

// Offset หน้าก่อนหน้า
const prevOffset = Math.max(0, offset - limit);

ทรัพยากรที่เกี่ยวข้อง


ถัดไป: เรียนรู้เกี่ยวกับ ความเป็นเอกภาพ เพื่อลองคำขอใหม่อย่างปลอดภัยโดยไม่ทำการซ้ำ