處理清單作業

部分服務會傳回可能很長的項目清單,例如資料列或資源說明。為控制 CPU 和記憶體用量,服務會以 pages 傳回這些資源:較小的項目子集,並附上接續權杖,用於要求下一個子集。

逐頁疊代項目可能很繁瑣。用戶端程式庫提供轉接器,可將頁面轉換為非同步疊代器。本指南說明如何使用這些轉接程式。

必要條件

本指南使用 Secret Manager 服務示範清單作業。本指南中的概念也適用於其他服務。

如要按照本指南操作,您必須啟用 Secret Manager 服務、登入帳戶,並確認帳戶具備必要權限。如需滿足這些必要條件的指引,請參閱服務快速入門導覽課程。

如需 Rust 程式庫的完整設定操作說明,請參閱「設定開發環境」。

依附元件

將 Secret Manager 程式庫新增至 Cargo.toml 檔案:

cargo add google-cloud-secretmanager-v1

疊代清單方法

為協助疊代清單方法中的項目,API 會傳回 ItemPaginator 特徵的實作。使用 use 宣告將特徵引入範圍:

use google_cloud_gax::paginator::ItemPaginator as _;

如要疊代項目,請使用 by_item 方法。

let mut list = client
    .list_secrets()
    .set_parent(format!("projects/{project_id}"))
    .by_item();
while let Some(secret) = list.next().await {
    let secret = secret?;
    println!("  secret={}", secret.name)
}

在少數情況下,頁面可能包含您需要存取的額外資訊,或者您可能需要檢查各個程序的進度。如有需要,您可以逐一查看完整頁面,而非個別項目。

  1. 使用 use 宣告將 Paginator 引入範圍:

    use google_cloud_gax::paginator::Paginator as _;

  2. 使用 by_page 疊代頁面:

    let mut list = client
        .list_secrets()
        .set_parent(format!("projects/{project_id}"))
        .by_page();
    while let Some(page) = list.next().await {
        let page = page?;
        println!("  next_page_token={}", page.next_page_token);
        page.secrets
            .into_iter()
            .for_each(|secret| println!("    secret={}", secret.name));
    }

正在使用 futures::Stream

您可能想在非同步串流的大型 Rust 生態系統中使用這些 API,例如 tokio::Stream。方法如下:

  1. 在 google_cloud_gax crate 中啟用 unstable-streams 功能。這項功能的名稱旨在提醒您,這些 API 仍不穩定。只有在您準備好處理因 futures::Stream 特徵不相容變更而導致的中斷時,才應使用這些功能。

    cargo add google-cloud-gax --features unstable-stream
    
  2. 以下範例也使用 futures::stream::StreamExt 特徵,您可以新增 futures crate 來啟用。

    cargo add futures
    
  3. 新增必要的 use 宣告:

    use futures::stream::StreamExt;
    use google_cloud_gax::paginator::ItemPaginator as _;

  4. 使用 into_stream 函式將 ItemPaginator 轉換為 futures::Stream。

    let list = client
        .list_secrets()
        .set_parent(format!("projects/{project_id}"))
        .by_item()
        .into_stream();
    list.map(|secret| -> gax::Result<()> {
        println!("  secret={}", secret?.name);
        Ok(())
    })
    .fold(Ok(()), async |acc, result| -> gax::Result<()> {
        acc.and(result)
    })
    .await?;

同樣地,您可以使用 into_stream 函式將 Paginator 轉換為 futures::Stream。

let list = client
    .list_secrets()
    .set_parent(format!("projects/{project_id}"))
    .by_page()
    .into_stream();
list.enumerate()
    .map(|(index, page)| -> gax::Result<()> {
        println!("page={}, next_page_token={}", index, page?.next_page_token);
        Ok(())
    })
    .fold(Ok(()), async |acc, result| -> gax::Result<()> {
        acc.and(result)
    })
    .await?;

設定下一頁權杖,繼續執行清單方法

在某些情況下 (例如清單作業中斷),您可以設定下一頁權杖,從特定頁面繼續分頁。

let page = client
    .list_secrets()
    .set_parent(format!("projects/{project_id}"))
    .send()
    .await;
let page = page?;
let mut next_page_token = page.next_page_token.clone();
page.secrets
    .into_iter()
    .for_each(|secret| println!("    secret={}", secret.name));

while !next_page_token.is_empty() {
    println!("  next_page_token={next_page_token}");

    let page = client
        .list_secrets()
        .set_parent(format!("projects/{project_id}"))
        .set_page_token(next_page_token)
        .send()
        .await;
    let page = page?;
    next_page_token = page.next_page_token.clone();

    page.secrets
        .into_iter()
        .for_each(|secret| println!("    secret={}", secret.name));
}

分頁器輔助程式的使用時機

如果 Google API 清單方法遵循 AIP-158 定義的分頁指南,Rust 的 Google Cloud 用戶端程式庫會提供轉接器,將 AIP-4233 定義的清單 RPC 轉換為實作 ItemPaginator 和 Paginator 的類型。簡而言之,這項指南要求每次呼叫 List 方法時,都必須傳回一頁資源項目 (例如 Secret),以及可傳遞至 List 方法以擷取下一頁的權杖。

大多數 Google Cloud 服務都遵循這些規範。如果沒有,您必須自行實作轉接程式,才能疊代結果。