Skip to content

Dolck/lambda-web

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

lambda-web

Run Actix web, Rocket, Warp on AWS Lambda

crates.io API docs

Features

Web frameworks

Supported

AWS infrastructure

Supported

Not supported

  • API Gateway HTTP API with payload format version 1.0
  • API Gateway REST API
  • Application Load Balancer (ALB)

Example

Actix Web

Cargo.toml

[[bin]]
name = "bootstrap"
path = "src/main.rs"

[dependencies]
lambda-web = { version = "0.1.6", features=["actix4"] }

main.rs

use lambda_web::actix_web::{self, get, App, HttpServer, Responder};
use lambda_web::{is_running_on_lambda, run_actix_on_lambda, LambdaError};

#[get("/")]
async fn hello() -> impl Responder {
    format!("Hello")
}

#[actix_web::main]
async fn main() -> Result<(),LambdaError> {
    let factory = move || {
        App::new().service(hello)
    };

    if is_running_on_lambda() {
        // Run on AWS Lambda
        run_actix_on_lambda(factory).await?;
    } else {
        // Local server
        HttpServer::new(factory)
            .bind("127.0.0.1:8080")?
            .run()
            .await?;
    }
    Ok(())
}

Rocket

Cargo.toml

[[bin]]
name = "bootstrap"
path = "src/main.rs"

[dependencies]
lambda-web = { version = "0.1.6", features=["rocket05"] }
rocket = "0.5.0-rc.1"

main.rs

use rocket::{self, get, routes};
use lambda_web::{is_running_on_lambda, launch_rocket_on_lambda, LambdaError};

#[get("/hello/<name>/<age>")]
fn hello(name: &str, age: u8) -> String {
    format!("Hello, {} year old named {}!", age, name)
}

#[rocket::main]
async fn main() -> Result<(), LambdaError> {
    let rocket = rocket::build().mount("/", routes![hello]);
    if is_running_on_lambda() {
        // Launch on AWS Lambda
        launch_rocket_on_lambda(rocket).await?;
    } else {
        // Launch local server
        rocket.launch().await?;
    }
    Ok(())
}

Warp

Cargo.toml

[[bin]]
name = "bootstrap"
path = "src/main.rs"

[dependencies]
lambda-web = { version = "0.1.6", features=["warp03"] }
tokio = { version = "1" }

main.rs

use lambda_web::warp::{self, Filter};
use lambda_web::{is_running_on_lambda, run_warp_on_lambda, LambdaError};

#[tokio::main]
async fn main() -> Result<(), LambdaError> {
    // GET /hello/warp => 200 OK with body "Hello, warp!"
    let hello = warp::path!("hello" / String).map(|name| format!("Hello, {}", name));

    if is_running_on_lambda() {
        // Run on AWS Lambda
        run_warp_on_lambda(warp::service(hello)).await?;
    } else {
        // Run local server
        warp::serve(hello).run(([127, 0, 0, 1], 8080)).await;
    }
    Ok(())
}

Create deploy ZIP file

Currentry (Jun 2021), we have two options to run Rust on AWS Lambda: Amazon Linux 2 custom runtime or Docker container image.

I recommend Amazon Linux 2 custom runtime deploy because it's faster cold start time than container image.

To build Amazon Linux 2 compatible binary, it's better to build inside container. First, build Amazon Linux 2 container with Rust toolchain. This repository contains sample Dockerfile .

$ git clone https://github.com/hanabu/lambda-web
...
$ docker build -t lambda_builder lambda-web/docker
...

or
$ buildah bud -t lambda_builder lambda-web/docker
...

Once you get lambda_builder image, then build your code with Amazon Linux.

$ cd your_app_crate_dir
$ docker run -it --rm -v ~/.cargo/registry:/root/.cargo/registry:z -v .:/build:z lambda_builder
...

or
$ podman run -it --rm -v ~/.cargo/registry:/root/.cargo/registry:z -v .:/build:z lambda_builder
...

Then, you get deploy ZIP package in your_app_crate_dir/target_lambda/deploy.zip .

Make sure, your Cargo.toml has bootstrap binary name.

[[bin]]
name = "bootstrap"
path = "src/main.rs"

Setup AWS Lambda & API gateway

Lambda

  • Create lambda function with provided.al2 custom runtime. Choose "Provide your own bootstrap on Amazon Linux 2" .
  • Upload ZIP file described above.
  • IAM role, memory settings, etc. are as your demands.
    As sample code above consumes only 30MB of memory, many simple Rust app can fit in 128MB setting.

API Gateway

  • Create HTTP API
  • Create single route "$default" and attach Lambda integration. Make sure, payload format version is "2.0"

About

Run Rust web frameworks on AWS Lambda

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Rust 98.7%
  • Dockerfile 1.3%