處理清單作業

部分服務會傳回可能包含大量項目的清單,例如資料列或資源說明。為控管 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 Cloud Rust 適用的用戶端程式庫提供轉接器,可將 AIP-4233 定義的清單 RPC 轉換為實作 ItemPaginatorPaginator 的型別 (如果 Google API 清單方法遵循 AIP-158 定義的分頁指南)。簡而言之,這項指南規定每次呼叫 List 方法時,都必須傳回一頁資源項目 (例如密鑰),以及可傳遞至 List 方法的權杖,用於擷取下一頁。

大多數 Google Cloud 服務都遵循這些規範。如果沒有,您必須實作自己的轉接程式,才能逐一查看結果。