Paginating in the SDK for Rust
This section describes how to handle cases where an API does not return all of the available objects in a single request. Instead, the API will return a portion of the data and a token to retrieve further items. This pattern is called pagination. AWS SDK for Rust exposes a method on many operations called into_paginator
. When calling this method before executing the request, you can iterate or collect all items asynchronously. When at the end of a page, AWS SDK for Rust will automatically request the next page of data. Here is an example of using into_paginator
to list all tables in Amazon DynamoDB, even with a limit on the size of the page.
pub async fn list_items(client: &Client, table: &str, page_size: Option<i32>) -> Result<(), Error> { let page_size = page_size.unwrap_or(10); let items: Result<Vec<_>, _> = client .scan() .table_name(table) .limit(page_size) .into_paginator() .items() .send() .collect() .await; println!("Items in table (up to {page_size}):"); for item in items? { println!(" {:?}", item); } Ok(()) }
Sometimes, you will want to have more control over paging. In these
cases, you should review the documentation for the service you're using to
see what properties are used for paging tokens. Here is an example that
lists tables and checks the last_evaluated_table_name
field to
determine if the paging has completed.
pub async fn list_tables_are_more(client: &Client) -> Result<(), Error> { let resp = client.list_tables().limit(10).send().await?; println!("Tables:"); let names = resp.table_names(); for name in names { println!(" {}", name); } println!(); println!("Found {} tables", names.len()); if resp.last_evaluated_table_name.is_some() { println!("There are more tables"); } Ok(()) }
To loop through pages of results, you might need to use mut
variables. Here is the same example, checking the last_evaluated_table_name
field in a loop to get all pages. It prints -- more --
between each page.
let mut resp = client.list_tables().limit(10).send().await?; let mut names = resp.table_names.unwrap_or_default(); let len = names.len(); let mut num_tables = len; println!("Tables:"); for name in &names { println!(" {}", name); } while resp.last_evaluated_table_name.is_some() { println!("-- more --"); resp = client .list_tables() .limit(10) .exclusive_start_table_name( resp.last_evaluated_table_name .as_deref() .unwrap_or_default(), ) .send() .await?; let mut more_names = resp.table_names.unwrap_or_default(); num_tables += more_names.len(); for name in &more_names { println!(" {}", name); } names.append(&mut more_names); } println!(); println!("Found {} tables", num_tables); Ok(names)