Bir API'nin /siparisler uç noktası tüm siparişleri tek seferde döndürüyorsa, bugün sorun yoktur. İki yıl sonra yüz bin siparişle bu uç nokta hem sunucuyu hem istemciyi kilitler. Sayfalama, büyük listeleri yönetilebilir parçalara bölmenin standart yoludur ve API tasarımının baştan düşünülmesi gereken parçalarındandır.
Offset sayfalama
En bilinen yöntemdir: "20 kayıt atla, sonraki 20'yi ver."
GET /siparisler?sayfa=3&boyut=20
SELECT ... ORDER BY Tarih DESC, Id DESC
OFFSET 40 ROWS FETCH NEXT 20 ROWS ONLY;
Artıları: Basit, belirli bir sayfaya doğrudan atlanabilir, sayfa numaralı arayüzlerle uyumlu.
Eksileri:
- Sayfa numarası büyüdükçe yavaşlar; veritabanı atlanan satırları da okur.
- Listeye yeni kayıt eklenirse kayıtlar kayar: aynı kayıt iki sayfada görünebilir veya bir kayıt hiç görünmeyebilir.
Cursor (keyset) sayfalama
"Son gördüğüm kayıttan sonrakileri ver" mantığıyla çalışır:
GET /siparisler?sonraki=eyJ0IjoiMjAyNi0xMC0wNSIsImlkIjo5ODc2fQ&boyut=20
SELECT TOP 20 ... FROM Siparisler
WHERE (Tarih < @sonTarih) OR (Tarih = @sonTarih AND Id < @sonId)
ORDER BY Tarih DESC, Id DESC;
Artıları: Sayfa ne kadar ileride olursa olsun hızlıdır (doğru indeksle), yeni kayıtlar eklense de kayma olmaz.
Eksileri: Belirli bir sayfa numarasına atlanamaz; sıralama alanları sabit olmalıdır.
Karşılaştırma
| Offset | Cursor | |
|---|---|---|
| Uygun arayüz | Sayfa numaralı tablolar, yönetim panelleri | Sonsuz kaydırma, mobil, entegrasyonlar |
| Derin sayfalarda performans | Kötüleşir | Sabit |
| Veri değişirken tutarlılık | Kayma olabilir | Tutarlı |
| Uygulama kolaylığı | Kolay | Orta |
Ortak kurallar
- Kararlı sıralama: Sıralamada her zaman benzersiz bir alan (Id) bulunmalıdır; aksi halde aynı tarihli kayıtların sırası sorgudan sorguya değişebilir.
- Sayfa boyutu sınırı: İstemci
boyut=100000gönderemesin; makul bir üst sınır koyun. - Toplam sayı dikkatli:
COUNT(*)büyük tablolarda pahalıdır. Gerçekten gerekiyorsa ayrı veya isteğe bağlı sunun. - Cursor'ı opak tutun: İçeriği base64 gibi bir biçimde kodlayın; istemci içini yorumlamaya çalışmasın, siz de formatı ileride değiştirebilin.
Yanıt formatı
{
"veri": [ ... ],
"sonraki": "eyJ0IjoiMjAyNi0xMC0wNSIsImlkIjo5ODc2fQ",
"dahaVar": true
}
Tutarlı bir yanıt yapısı, API'yi kullananların işini kolaylaştırır. Hata yanıtları için de benzer bir standart kullanın: Problem Details. API tasarımının diğer temelleri için bkz. REST API.
Sık sorulan sorular
Yönetim panelinde hangisini kullanmalıyım?
Kullanıcılar genellikle ilk birkaç sayfaya bakar ve filtre kullanır; offset sayfalama çoğu panel için yeterlidir.
Entegrasyonlarda tüm veriyi çekmek gerekiyorsa?
Cursor sayfalama veya "şu tarihten sonra değişenler" filtresiyle artımlı senkronizasyon en güvenilir yoldur.
Sonuç
Sayfalama, API'nin bugün değil yıllar sonra da hızlı kalmasını sağlar. Kullanıcı arayüzü için offset, büyük ve sürekli değişen veri ile entegrasyonlar için cursor yaklaşımı genellikle en doğru seçimdir.