दस्तावेज़ पर जाएँ
Ruby

पेजिनेशन

हर पेज वाली सूची पर एक पेज, सभी पेज, या एक बार में एक आइटम।

list, list_all और iterate

पेज वाली हर सूची के तीन मेथड होते हैं। list एक पेज लाता है और एक OpenEmail::Page लौटाता है। list_all हर पेज में cursor का पीछा करता है और एक Array लौटाता है। iterate उन्हीं पेजों पर एक बार में एक आइटम चलता है: वह हर आइटम को एक block में yield करता है, या जब आप block न दें तो एक Enumerator लौटाता है। तीनों सूची के फ़िल्टर, limit:, cursor: और api_key: लेते हैं।

three_ways.rb
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?

जहाँ भी किसी namespace में एक से ज़्यादा सूची हो, वही तीन नाम दोहराए जाते हैं, उस सूची के नाम पर जिस पर वे चलते हैं: emails पर list_events, list_all_events और iterate_events, webhooks पर list_deliveries, list_all_deliveries और iterate_deliveries, इत्यादि।

OpenEmail::Page

itemsArray<Hash>
इस पेज की पंक्तियाँ, API के `data` envelope से बाहर निकाली गईं, हर एक Symbol कुंजियों वाला Hash। जब पेज में कुछ न हो तो ख़ाली।
has_more?Boolean
क्या इसके बाद कोई और पेज है। प्रश्नचिह्न के बिना `has_more` वही मान पढ़ता है। जब API कोई `hasMore` नहीं भेजता, तो यह ठीक तभी true होता है जब कोई `next_cursor` हो।
next_cursorString or nil
अगले पेज के लिए `cursor:` के रूप में क्या वापस भेजना है, और आख़िरी पेज पर nil।

पेज एक Ruby Data ऑब्जेक्ट है, इसलिए वह frozen है, मान के आधार पर तुलना होता है, और to_h से Hash में बदल जाता है।

एक block या एक Enumerator

block मिलने पर iterate अभी ही हर पेज पर चलता है और हर आइटम उसे yield करता है। block के बिना वह एक Enumerator लौटाता है और तब तक कुछ नहीं लाता जब तक आप उसे इस्तेमाल न करें। दोनों ही तरह, वह अगला पेज तभी माँगता है जब मौजूदा पेज का हर आइटम yield हो चुका हो, इसलिए जो कुछ भी जल्दी रुकता है वह रिक्वेस्ट भी रोक देता है: first(10) सिर्फ़ उतने पेज पढ़ता है जितने दस आइटम के लिए ज़रूरी हों, find मिलान पर रुक जाता है, और block में break चलना ख़त्म कर देता है।

enumerator.rb
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] }

Enumerable का कोई मेथड जिसे हर आइटम चाहिए, जैसे सीधे Enumerator पर कॉल किया गया select, map या count, लौटने से पहले हर पेज पढ़ता है, जैसा list_all करता है। उन्हें जोड़ते हुए भी जल्दी रुकने के लिए आगे lazy लगाएँ।

Enumerator हर बार इस्तेमाल होने पर अपना चलना फिर से शुरू करता है, इसलिए उसी पर first(10) दो बार कॉल करने से पहला पेज दो बार आता है। जब दोबारा ज़रूरत हो तो Enumerator नहीं, नतीजा रखें।

cursor से आगे बढ़ना

cursor अपारदर्शी होता है। आपने जो आख़िरी पेज पढ़ा उसका next_cursor रखें और वहीं से आगे बढ़ने के लिए उसे cursor: के रूप में वापस भेजें, किसी बाद की रिक्वेस्ट में या किसी दूसरे प्रोसेस में। list_all और iterate भी cursor: लेते हैं, और उसके बाद से चलना शुरू करते हैं।

resume.rb
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.sizeend

cursor उसी सूची और उन्हीं फ़िल्टरों का होता है जिनसे वह आया, इसलिए उसके साथ वही फ़िल्टर भेजें। जिस cursor को सूची पहचान न सके उसे invalid_cursor के साथ अस्वीकार किया जाता है, और तब हल यही है कि बिना cursor के फिर से शुरू करें।

limit:

limit: हर पेज का आकार है, कुल संख्या नहीं। list पर यह है कि कितनी पंक्तियाँ लौटती हैं। list_all और iterate पर यह है कि हर रिक्वेस्ट कितनी माँगती है, इसलिए बड़ा मान यानी उन्हीं पंक्तियों के लिए कम आवाजाही। हर सूची की अपनी सीमा और डिफ़ॉल्ट होता है, अक्सर 1 से 100, और कुछ न भेजने पर 25, और सीमा से बाहर का मान सीमा में काटे जाने के बजाय अस्वीकार किया जाता है। हर सूची का पेज उसकी सीमा बताता है।

चलना कब रुकता है

  • जब कोई पेज कहे कि has_more? false है।
  • जब किसी पेज में कोई next_cursor न हो, क्योंकि जो पेज और होने का दावा करे पर कोई cursor न बताए वह हमेशा के लिए लूप में घूमता रहता।
  • जब API वही cursor लौटा दे जो उसे अभी दिया गया था, उसी कारण से।

हर पेज एक GET है, इसलिए कुछ भी raise होने से पहले किसी भी read की तरह उस पर अलग से पुनः प्रयास होता है। जो विफलता पुनः प्रयासों के बाद भी बनी रहे वह list_all से बाहर raise होती है, और पहले से लाए गए आइटम छोड़ दिए जाते हैं। iterate में तब तक पिछले पेजों के आइटम yield हो चुके होते हैं, इसलिए block जो करता है उसे दो बार चलने पर भी सुरक्षित बनाएँ, या list से पेज करें और हर next_cursor रखें ताकि दूसरा प्रयास वहीं से शुरू हो सके जहाँ पहला रुका था।

थ्रेड और ड्राफ़्ट

threads.list और drafts.list, अपने list_all और iterate के साथ, cursor के बजाय API के pageToken और nextPageToken से पेज करते हैं। gem यह अंतर छिपा देता है: टोकन को cursor: के रूप में पास करें और उसे next_cursor से पढ़ें।

page_token.rb
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&.size

जब भी कोई पेज भरा हुआ लौटता है, सर्वर एक टोकन देता है, इसलिए जो पेज असल में आख़िरी निकले उस पर भी has_more? true हो सकता है, और तब अगली कॉल कोई आइटम नहीं लौटाती।

ऐसे पेज जिनमें और भी कुछ होता है

कुछ सूचियाँ पंक्तियों से ज़्यादा के साथ जवाब देती हैं, और OpenEmail::Page की जगह अपना ख़ुद का Data ऑब्जेक्ट लौटाती हैं।

मेथडक्या लौटाता हैयह क्या जोड़ता है
addresses.listOpenEmail::AddressBookPageitems की जगह addresses, साथ में unrestricted और domains, has_more? और next_cursor के साथ।
addresses.list_allOpenEmail::AddressBookaddresses में हर पता, unrestricted और domains के साथ जैसा आख़िरी पेज ने उन्हें बताया। यह अकेला list_all है जो Array के बजाय पूरी पता-पुस्तिका लौटाता है। addresses.iterate सिर्फ़ पते yield करता है।
contacts.list_peopleOpenEmail::PeoplePageseen, जो तब false होता है जब कुंजी मेल में दिखे पते नहीं पढ़ सकती। list_all_people और iterate_people सिर्फ़ लोगों को लौटाते हैं।
temp_mail.list_messagesOpenEmail::TempMessagesPageexpires_at, जब इनबॉक्स की मियाद ख़त्म होती है। list_all_messages और iterate_messages सिर्फ़ संदेश लौटाते हैं।
templates.list_sendsOpenEmail::TemplateSendscursor के बजाय संख्या से पेज होता है: items, total, page और page_size। अगला पेज page: से माँगें।
emails.send_batchOpenEmail::BatchResultपेज नहीं: items, आपके भेजे हर संदेश के लिए एक, sent और failed गिनती के साथ।

ऐसी सूचियाँ जो API का Hash लौटाती हैं

कुछ सूचियाँ offset, पेज नंबर या अपने ख़ुद के संख्यात्मक cursor से पेज करती हैं, और OpenEmail::Page के बजाय पार्स की गई बॉडी जैसी आई वैसी लौटाती हैं, यानी data वाला एक Hash। इनमें list_all या iterate नहीं है, इसलिए पेजिंग आपको ख़ुद करनी होती है।

मेथडकिससे पेज होता हैक्या लौटता है
exports.listlimit: और offset:data, total और hasMore।
imports.list_failuresafter: और limit:data, और nextCursor, एक Integer जिसे after: के रूप में वापस भेजना है और जो आख़िरी पेज पर nil होता है।
subscriptions.list और subscriptions.list_domainslimit: और offset:data, total, counts और hasMore।
billing.list_invoicespage: और limit:data, total, page, limit, hasMore और metered।
offset_paging.rb
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].sizeend

जो सूची बिल्कुल पेज नहीं होती, जैसे languages.list, labels.list_colors या roles.list_permissions, वह सीधे एक Array लौटाती है।