Rust Screenshot API Quick Start
Add the snapapi crate and tokio async runtime to your Cargo.toml and initialize the async SnapAPI client with the API key loaded from the SNAPAPI_KEY environment variable. The Rust SDK uses async/await built on Tokio, returning Result types for all screenshot operations so that errors are handled explicitly at the call site rather than through unwrap panics in production code.
use snapapi::{Client, ScreenshotOptions};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let client = Client::new(std::env::var("SNAPAPI_KEY")?);
let result = client.screenshot(
ScreenshotOptions::builder()
.url("https://example.com")
.format("png")
.full_page(true)
.width(1280)
.build(),
).await?;
std::fs::write("screenshot.png", &result.image)?;
println!("Captured {} bytes", result.image.len());
Ok(())
}
Concurrent Rust Screenshot Capture with Tokio
Tokio's join_all and FuturesUnordered primitives enable concurrent screenshot capture across many URLs with precise control over concurrency level using a semaphore. Create an Arc-wrapped Semaphore initialized to the desired concurrency limit and clone the Arc into each spawned task. Each task acquires a semaphore permit before calling the SnapAPI client, releases the permit when the screenshot completes, and returns the result through the join handle. Collect all join handles into a Vec and await them with join_all to process all screenshots concurrently while respecting the concurrency limit.
use std::sync::Arc;
use tokio::sync::Semaphore;
use futures::future::join_all;
async fn capture_all(client: &Client, urls: Vec, limit: usize)
-> Vec>>
{
let sem = Arc::new(Semaphore::new(limit));
let handles: Vec<_> = urls.into_iter().map(|url| {
let client = client.clone();
let sem = sem.clone();
tokio::spawn(async move {
let _permit = sem.acquire().await?;
let r = client.screenshot(
ScreenshotOptions::builder().url(&url).build()
).await?;
Ok(r.image)
})
}).collect();
join_all(handles).await.into_iter()
.map(|h| h.map_err(Into::into).and_then(|r| r))
.collect()
}
Rust Screenshot API Axum Web Server
Axum web applications exposing screenshot endpoints define a handler function that extracts the URL from a query parameter struct, validates it, calls the SnapAPI async client, and returns the PNG bytes in a Response with a Content-Type: image/png header. Share the SnapAPI client across handler invocations using Axum's State extractor with an Arc-wrapped client, avoiding re-initialization on every request. Add a tower_http rate limit layer to the Axum router to cap the number of concurrent screenshot requests from each client IP, preventing individual clients from exhausting the SnapAPI plan limit during traffic spikes. Deploy the Axum service as a Docker container using the official Rust builder image with a multi-stage Dockerfile that produces a minimal final image containing only the compiled binary and TLS certificates.
Rust Screenshot API with AWS Lambda
Rust is an excellent choice for AWS Lambda screenshot handlers due to its fast cold start time and minimal memory footprint compared to JVM-based or interpreted language runtimes. Use the aws-lambda-rust-runtime crate to define a Lambda handler function that accepts an API Gateway proxy request event, extracts the URL query parameter, calls the SnapAPI async client using the handler's Tokio runtime, and returns the screenshot bytes base64-encoded in a Lambda proxy response with Content-Type: image/png. Compile the Lambda handler to the x86_64-unknown-linux-musl target for a statically linked binary that runs on AWS Lambda's Amazon Linux 2 execution environment without runtime dependencies. Deploy the binary using the provided.al2 Lambda runtime and configure the Lambda function URL or API Gateway integration to proxy screenshot requests directly to the Lambda handler for a fully serverless screenshot API endpoint that scales to zero between requests.
Rust Screenshot API Error Handling and Retries
Rust's Result-based error handling enables precise retry logic for SnapAPI integrations that distinguishes between retryable and non-retryable errors without relying on exception types. Define a custom SnapApiError enum with variants for RateLimit containing a retry-after duration, InvalidUrl containing the validation message, NetworkError wrapping the underlying reqwest error, and ServerError containing the HTTP status code. Implement a retry wrapper function that calls the SnapAPI client, matches on the error variant to determine whether to retry, and uses Tokio's sleep with exponential backoff for rate limit errors while returning immediately for non-retryable errors like invalid URL. The tokio-retry crate provides a configurable retry strategy combinator that integrates with async functions, simplifying the retry implementation to a configuration struct and a single retry call rather than a manual retry loop with backoff calculation.