Module actix

Module actix 

Source
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:

MethodPathDescription
GET/pdf?url=...Convert URL to PDF
POST/pdf/htmlConvert HTML to PDF
GET/pool/statsPool statistics
GET/healthHealth check
GET/readyReadiness 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

HandlerMethodDefault PathDescription
pdf_from_urlGET/pdfConvert URL to PDF
pdf_from_htmlPOST/pdf/htmlConvert HTML to PDF
pool_statsGET/pool/statsPool statistics
health_checkGET/healthHealth check (always 200)
readiness_checkGET/readyReadiness check (checks pool)

§Type Aliases

TypeDescription
SharedPoolArc<Mutex<BrowserPool>> - for service functions
BrowserPoolDataweb::Data<SharedBrowserPool> - for handler parameters

§Helper Functions

FunctionDescription
configure_routesConfigure all pre-built routes
create_pool_dataWrap SharedBrowserPool in web::Data
create_pool_data_from_arcWrap Arc<Mutex<BrowserPool>> in web::Data

§Extension Traits

TraitDescription
BrowserPoolActixExtAdds into_actix_data() to BrowserPool

Traits§

BrowserPoolActixExt
Extension trait for BrowserPool with Actix-web helpers.

Functions§

configure_routes
Configure all PDF routes.
create_pool_data
Create Actix-web Data from an existing shared pool.
create_pool_data_from_arc
Create Actix-web Data from an Arc reference.
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§

BrowserPoolData
Type alias for Actix-web Data wrapper around the shared pool.
SharedPool
Type alias for shared browser pool.