Sayfalama
Sayfalanan her listede tek sayfa, tüm sayfalar ya da her seferinde bir öğe.
list, list_all ve iterate
Sayfalanan her listenin üç metodu vardır. list bir sayfa getirir ve bir OpenEmail::Page döndürür. list_all cursor'ı tüm sayfalar boyunca izler ve tek bir Array döndürür. iterate aynı sayfaları her seferinde bir öğe olacak şekilde dolaşır: her öğeyi bir bloğa verir ya da blok vermezseniz bir Enumerator döndürür. Üçü de listenin filtrelerini, limit:, cursor: ve api_key: alır.
page = client.emails.list(status: "failed", limit: 50)page.items.each { |email| puts "#{email[:id]} #{email[:lastError]}" } failures = client.emails.list_all(status: "failed") client.emails.iterate(status: "failed") do |email| puts email[:id]end puts failures.size, page.has_more?Bir ad alanında birden fazla liste olduğu her yerde aynı üç ad, dolaştıkları listeye göre adlandırılarak tekrarlanır: emails üzerinde list_events, list_all_events ve iterate_events; webhooks üzerinde list_deliveries, list_all_deliveries ve iterate_deliveries ve benzerleri.
OpenEmail::Page
itemsArray<Hash>- Bu sayfanın satırları; API'nin `data` zarfından çıkarılmış, her biri Symbol anahtarlı bir Hash. Sayfa hiçbir şey içermiyorsa boştur.
has_more?Boolean- Ardından başka bir sayfa gelip gelmediği. Soru işareti olmayan `has_more` aynı değeri okur. API `hasMore` göndermediğinde değer, tam olarak bir `next_cursor` olduğunda true olur.
next_cursorString or nil- Sonraki sayfa için `cursor:` olarak geri geçirilecek değer. Son sayfada nil.
Bir sayfa bir Ruby Data nesnesidir; bu yüzden dondurulmuştur, değere göre karşılaştırılır ve to_h ile bir Hash'e dönüşür.
Bir blok ya da bir Enumerator
Bir blok verildiğinde iterate tüm sayfaları hemen dolaşır ve her öğeyi bloğa verir. Blok olmadan bir Enumerator döndürür ve siz onu tüketene kadar hiçbir şey getirmez. Her iki durumda da bir sonraki sayfayı ancak geçerli sayfanın tüm öğeleri verildikten sonra ister; bu yüzden erken duran her şey istekleri de durdurur: first(10) yalnızca on öğe için gereken kadar sayfa okur, find eşleşmede durur ve bir bloktaki break dolaşmayı bitirir.
latest = client.emails.iterate(status: "failed", limit: 100).first(10) invoice = client.emails.iterate(status: "failed").find do |email| email.dig(:tags, :invoice) == "inv_2026_09_4192"end from_api = client.emails.iterate(status: "bounced").lazy.select { |email| email[:source] == "api" }.first(5) p latest.size, invoice&.fetch(:id), from_api.map { |email| email[:id] }Doğrudan Enumerator üzerinde çağrılan select, map ya da count gibi her öğeye ihtiyaç duyan bir Enumerable metodu, list_all gibi dönmeden önce tüm sayfaları okur. Bunları zincirleyip yine de erken durabilmek için başa lazy koyun.
Bir Enumerator her tüketildiğinde dolaşmaya baştan başlar; bu yüzden aynı Enumerator üzerinde first(10) çağrısını iki kez yapmak ilk sayfayı iki kez getirir. Sonuca yeniden ihtiyacınız olacaksa Enumerator'ı değil, sonucu saklayın.
Bir cursor'dan devam etme
Bir cursor opaktır. Okuduğunuz son sayfanın next_cursor değerini saklayın ve daha sonraki bir istekte ya da başka bir süreçte oradan devam etmek için onu cursor: olarak geri geçirin. list_all ve iterate de cursor: alır ve dolaşmaya onun ardından başlar.
first_page = client.emails.list(status: "failed", limit: 25)saved = first_page.next_cursor if saved rest = client.emails.list_all(status: "failed", cursor: saved) puts rest.sizeendBir cursor, geldiği listeye ve filtrelere aittir; bu yüzden onunla birlikte aynı filtreleri gönderin. Listenin yerleştiremediği bir cursor invalid_cursor ile reddedilir ve bu durumda çözüm, cursor olmadan baştan başlamaktır.
limit:
limit: toplam değil, her sayfanın boyutudur. list üzerinde kaç satır döneceğidir. list_all ve iterate üzerinde her isteğin kaç satır istediğidir; bu yüzden daha büyük bir değer aynı satırlar için daha az gidiş dönüş anlamına gelir. Her listenin kendi aralığı ve varsayılanı vardır; çoğunlukla 1 ile 100 arasıdır ve hiçbir şey göndermezseniz 25'tir. Aralık dışındaki bir değer kırpılmaz, reddedilir. Her listenin sayfası kendi aralığını belirtir.
Bir dolaşma ne zaman durur
- Bir sayfa
has_more?değerinin false olduğunu söylediğinde. - Bir sayfa
next_cursortaşımadığında, çünkü devamı olduğunu iddia edip hiçbir cursor belirtmeyen bir sayfa sonsuza dek döngüye girerdi. - API kendisine az önce verilen cursor'ı geri verdiğinde, aynı nedenle.
Her sayfa bir GET'tir; bu yüzden herhangi bir hata fırlatılmadan önce her okuma gibi kendi başına yeniden denenir. Yeniden denemelerden sonra da süren bir hata list_all dışına fırlatılır ve o ana kadar getirilen öğeler atılır. iterate içinde ise önceki sayfaların öğeleri o zamana kadar zaten verilmiştir; bu yüzden bloğun yaptığı işi iki kez çalışmaya karşı güvenli hâle getirin ya da list ile sayfalayıp her next_cursor değerini saklayın, böylece ikinci bir deneme ilkinin durduğu yerden başlayabilir.
Konuşma dizileri ve taslaklar
threads.list ve drafts.list, list_all ve iterate metotlarıyla birlikte, bir cursor yerine API'nin pageToken ve nextPageToken değerleriyle sayfalar. Gem bu farkı gizler: tokenı cursor: olarak geçirin ve next_cursor üzerinden okuyun.
page = client.threads.list(folder: "inbox", limit: 50)later = client.threads.list(folder: "inbox", limit: 50, cursor: page.next_cursor) if page.has_more? p page.items.size, later&.items&.sizeSunucu, bir sayfa dolu döndüğünde her seferinde bir token sunar; bu yüzden has_more? sonradan son sayfa olduğu anlaşılan bir sayfada true olabilir ve bu durumda bir sonraki çağrı hiç öğe döndürmez.
Daha fazlasını taşıyan sayfalar
Birkaç liste satırlardan fazlasıyla yanıt verir ve OpenEmail::Page yerine kendine ait bir Data nesnesi döndürür.
| Metot | Döndürdüğü | Ne ekler |
|---|---|---|
| addresses.list | OpenEmail::AddressBookPage | items yerine addresses, ayrıca unrestricted ve domains, has_more? ve next_cursor ile birlikte. |
| addresses.list_all | OpenEmail::AddressBook | Tüm adresler addresses içinde; unrestricted ve domains ise son sayfanın bildirdiği hâliyle. Bir Array yerine adres defterinin tamamını döndüren tek list_all budur. addresses.iterate yalnızca adresleri verir. |
| contacts.list_people | OpenEmail::PeoplePage | seen: anahtar postada görülen adresleri okuyamadığında false. list_all_people ve iterate_people yalnızca kişileri döndürür. |
| temp_mail.list_messages | OpenEmail::TempMessagesPage | expires_at: gelen kutusunun süresinin dolduğu an. list_all_messages ve iterate_messages yalnızca iletileri döndürür. |
| templates.list_sends | OpenEmail::TemplateSends | Cursor yerine numarayla sayfalanır: items, total, page ve page_size. Sonraki sayfayı page: ile isteyin. |
| emails.send_batch | OpenEmail::BatchResult | Bir sayfa değildir: gönderdiğiniz her ileti için bir tane olmak üzere items, sent ve failed sayılarıyla birlikte. |
API'nin Hash'ini döndüren listeler
Bazı listeler ofsetle, sayfa numarasıyla ya da kendilerine ait sayısal bir cursor ile sayfalar ve ayrıştırılmış gövdeyi bir OpenEmail::Page yerine geldiği gibi, data içeren bir Hash olarak döndürür. Bunların list_all ya da iterate metotları yoktur, bu yüzden sayfalamayı kendiniz yaparsınız.
| Metot | Sayfalama yöntemi | Ne döner |
|---|---|---|
| exports.list | limit: ve offset: | data, total ve hasMore. |
| imports.list_failures | after: ve limit: | data ve nextCursor: after: olarak geri geçirilecek, son sayfada nil olan bir Integer. |
| subscriptions.list ve subscriptions.list_domains | limit: ve offset: | data, total, counts ve hasMore. |
| billing.list_invoices | page: ve limit: | data, total, page, limit, hasMore ve metered. |
offset = 0 loop do batch = client.subscriptions.list(status: "active", limit: 50, offset:) batch[:data].each { |row| puts "#{row[:senderEmail]} #{row[:total]}" } break unless batch[:hasMore] offset += batch[:data].sizeendlanguages.list, labels.list_colors ya da roles.list_permissions gibi hiç sayfalanmayan bir liste doğrudan bir Array döndürür.