Expand description
Actix-web framework integration.
This module provides helpers and pre-built handlers for using BrowserPool
with Actix-web. You can choose between using the pre-built handlers for
quick setup, or writing custom handlers for full control.
§Quick Start
§Option 1: Pre-built Routes (Fastest Setup)
Use configure_routes to add all PDF endpoints with a single line:
ⓘ
use actix_web::{App, HttpServer, web};
use html2pdf_api::prelude::*;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let pool = init_browser_pool().await
.expect("Failed to initialize browser pool");
HttpServer::new(move || {
App::new()
.app_data(web::Data::new(pool.clone()))
.configure(html2pdf_api::integrations::actix::configure_routes)
})
.bind("127.0.0.1:8080")?
.run()
.await
}This gives you the following endpoints:
| Method | Path | Description |
|---|---|---|
| GET | /pdf?url=... | Convert URL to PDF |
| POST | /pdf/html | Convert HTML to PDF |
| GET | /pool/stats | Pool statistics |
| GET | /health | Health check |
| GET | /ready | Readiness check |
§Option 2: Mix Pre-built and Custom Handlers
Use individual pre-built handlers alongside your own:
ⓘ
use actix_web::{App, HttpServer, web};
use html2pdf_api::prelude::*;
use html2pdf_api::integrations::actix::{pdf_from_url, health_check};
async fn my_custom_handler() -> impl Responder {
// Your custom logic
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let pool = init_browser_pool().await?;
HttpServer::new(move || {
App::new()
.app_data(web::Data::new(pool.clone()))
// Pre-built handlers
.route("/pdf", web::get().to(pdf_from_url))
.route("/health", web::get().to(health_check))
// Custom handler
.route("/custom", web::get().to(my_custom_handler))
})
.bind("127.0.0.1:8080")?
.run()
.await
}§Option 3: Custom Handlers with Service Functions
For full control, use the service functions directly:
ⓘ
use actix_web::{web, HttpResponse, Responder};
use html2pdf_api::prelude::*;
use html2pdf_api::service::{generate_pdf_from_url, PdfFromUrlRequest};
async fn my_pdf_handler(
pool: web::Data<SharedBrowserPool>,
query: web::Query<PdfFromUrlRequest>,
) -> impl Responder {
// Custom pre-processing: auth, rate limiting, logging, etc.
log::info!("Custom handler: {}", query.url);
let pool = pool.into_inner();
let request = query.into_inner();
// Call service in blocking context
let result = web::block(move || {
generate_pdf_from_url(&pool, &request)
}).await;
match result {
Ok(Ok(pdf)) => {
// Custom post-processing
HttpResponse::Ok()
.content_type("application/pdf")
.insert_header(("X-Custom-Header", "value"))
.body(pdf.data)
}
Ok(Err(e)) => HttpResponse::BadRequest().body(e.to_string()),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}§Option 4: Full Manual Control (Original Approach)
For complete control over browser operations:
ⓘ
use actix_web::{web, HttpResponse, Responder};
use html2pdf_api::prelude::*;
async fn manual_pdf_handler(
pool: web::Data<SharedBrowserPool>,
) -> impl Responder {
let pool_guard = match pool.lock() {
Ok(guard) => guard,
Err(e) => return HttpResponse::InternalServerError().body(e.to_string()),
};
let browser = match pool_guard.get() {
Ok(b) => b,
Err(e) => return HttpResponse::ServiceUnavailable().body(e.to_string()),
};
let tab = browser.new_tab().unwrap();
tab.navigate_to("https://example.com").unwrap();
tab.wait_until_navigated().unwrap();
let pdf_data = tab.print_to_pdf(None).unwrap();
HttpResponse::Ok()
.content_type("application/pdf")
.body(pdf_data)
}§Setup
Add to your Cargo.toml:
[dependencies]
html2pdf-api = { version = "0.2", features = ["actix-integration"] }
actix-web = "4"§Graceful Shutdown
For proper cleanup, shutdown the pool when the server stops:
ⓘ
use actix_web::{App, HttpServer, web};
use html2pdf_api::prelude::*;
use std::sync::Arc;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let pool = init_browser_pool().await
.expect("Failed to initialize browser pool");
// Keep a reference for shutdown
let shutdown_pool = pool.clone();
let server = HttpServer::new(move || {
App::new()
.app_data(web::Data::new(pool.clone()))
.configure(html2pdf_api::integrations::actix::configure_routes)
})
.bind("127.0.0.1:8080")?
.run();
// Run server
let result = server.await;
// Cleanup pool after server stops
if let Ok(mut pool) = shutdown_pool.lock() {
pool.shutdown();
}
result
}§API Reference
§Pre-built Handlers
| Handler | Method | Default Path | Description |
|---|---|---|---|
pdf_from_url | GET | /pdf | Convert URL to PDF |
pdf_from_html | POST | /pdf/html | Convert HTML to PDF |
pool_stats | GET | /pool/stats | Pool statistics |
health_check | GET | /health | Health check (always 200) |
readiness_check | GET | /ready | Readiness check (checks pool) |
§Type Aliases
| Type | Description |
|---|---|
SharedPool | Arc<Mutex<BrowserPool>> - for service functions |
BrowserPoolData | web::Data<SharedBrowserPool> - for handler parameters |
§Helper Functions
| Function | Description |
|---|---|
configure_routes | Configure all pre-built routes |
create_pool_data | Wrap SharedBrowserPool in web::Data |
create_pool_data_from_arc | Wrap Arc<Mutex<BrowserPool>> in web::Data |
§Extension Traits
| Trait | Description |
|---|---|
BrowserPoolActixExt | Adds into_actix_data() to BrowserPool |
Traits§
- Browser
Pool Actix Ext - Extension trait for
BrowserPoolwith Actix-web helpers.
Functions§
- configure_
routes - Configure all PDF routes.
- create_
pool_ data - Create Actix-web
Datafrom an existing shared pool. - create_
pool_ data_ from_ arc - Create Actix-web
Datafrom anArcreference. - health_
check - Health check endpoint.
- pdf_
from_ html - Generate PDF from HTML content.
- pdf_
from_ url - Generate PDF from a URL.
- pool_
stats - Get browser pool statistics.
- readiness_
check - Readiness check endpoint.
Type Aliases§
- Browser
Pool Data - Type alias for Actix-web
Datawrapper around the shared pool. - Shared
Pool - Type alias for shared browser pool.