Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions CHANGELOG.md

This file was deleted.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = [
"lambda",
"lambda-http"
"lambda-http",
"lambda-runtime"
]
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@

This package makes it easy to run AWS Lambda Functions written in Rust. This workspace includes multiple crates:

- [![Docs](https://docs.rs/lambda/badge.svg)](https://docs.rs/lambda) **`lambda`** is a library that provides a Lambda runtime for applications written in Rust.
- [![Docs](https://docs.rs/lambda_runtime/badge.svg)](https://docs.rs/lambda_runtime) **`lambda-runtime`** is a library that provides a Lambda runtime for applications written in Rust.
- [![Docs](https://docs.rs/lambda_http/badge.svg)](https://docs.rs/lambda_http) **`lambda-http`** is a library that makes it easy to write API Gateway proxy event focused Lambda functions in Rust.

## Example function

The code below creates a simple function that receives an event with a `firstName` field and returns a message to the caller. Notice: this crate is tested against latest stable Rust.

```rust,no_run
use lambda::{handler_fn, Context};
use lambda_runtime::{handler_fn, Context};
use serde_json::{json, Value};

type Error = Box<dyn std::error::Error + Send + Sync + 'static>;

#[tokio::main]
async fn main() -> Result<(), Error> {
let func = handler_fn(func);
lambda::run(func).await?;
lambda_runtime::run(func).await?;
Ok(())
}

Expand All @@ -31,7 +31,7 @@ async fn func(event: Value, _: Context) -> Result<Value, Error> {
}
```

The code above is the same as the [basic example](https://github.com/awslabs/aws-lambda-rust-runtime/blob/master/lambda/examples/hello-without-macro.rs) in the `lambda` crate.
The code above is the same as the [basic example](https://github.com/awslabs/aws-lambda-rust-runtime/blob/master/lambda/examples/hello-without-macro.rs) in the `lambda_runtime` crate.

### Deployment

Expand All @@ -56,13 +56,13 @@ $ echo $'[target.x86_64-unknown-linux-musl]\nlinker = "x86_64-linux-musl-gcc"' >

Compile one of the examples as a _release_ with a specific _target_ for deployment to AWS:
```bash
$ cargo build -p lambda --example basic --release --target x86_64-unknown-linux-musl
$ cargo build -p lambda_runtime --example basic --release --target x86_64-unknown-linux-musl
```

For [a custom runtime](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html), AWS Lambda looks for an executable called `bootstrap` in the deployment package zip. Rename the generated `basic` executable to `bootstrap` and add it to a zip archive.

```bash
$ cp ./target/release/examples/hello ./bootstrap && zip lambda.zip bootstrap && rm bootstrap
$ cp ./target/x86_64-unknown-linux-musl/release/examples/hello ./bootstrap && zip lambda.zip bootstrap && rm bootstrap
```

Now that we have a deployment package (`lambda.zip`), we can use the [AWS CLI](https://aws.amazon.com/cli/) to create a new Lambda function. Make sure to replace the execution role with an existing role in your account!
Expand Down Expand Up @@ -127,7 +127,7 @@ $ npx serverless invoke -f hello -d '{"foo":"bar"}'

Alternatively, you can build a Rust-based Lambda function in a [docker mirror of the AWS Lambda provided runtime with the Rust toolchain preinstalled](https://github.com/softprops/lambda-rust).

Running the following command will start a ephemeral docker container which will build your Rust application and produce a zip file containing its binary auto-renamed to `bootstrap` to meet the AWS Lambda's expectations for binaries under `target/lambda/release/{your-binary-name}.zip`, typically this is just the name of your crate if you are using the cargo default binary (i.e. `main.rs`)
Running the following command will start a ephemeral docker container which will build your Rust application and produce a zip file containing its binary auto-renamed to `bootstrap` to meet the AWS Lambda's expectations for binaries under `target/lambda_runtime/release/{your-binary-name}.zip`, typically this is just the name of your crate if you are using the cargo default binary (i.e. `main.rs`)

```bash
# build and package deploy-ready artifact
Expand Down Expand Up @@ -159,12 +159,12 @@ $ unzip -o \

## `lambda`

`lambda` is a library for authoring reliable and performant Rust-based AWS Lambda functions. At a high level, it provides a few major components:
`lambda_runtime` is a library for authoring reliable and performant Rust-based AWS Lambda functions. At a high level, it provides a few major components:

- `Handler`, a trait that defines interactions between customer-authored code and this library.
- `lambda::run`, function that runs an `Handler`.
- `lambda_runtime::run`, function that runs an `Handler`.

The function `handler_fn` converts a rust function or closure to `Handler`, which can then be run by `lambda::run`.
The function `handler_fn` converts a rust function or closure to `Handler`, which can then be run by `lambda_runtime::run`.

## AWS event objects

Expand Down
6 changes: 3 additions & 3 deletions lambda-http/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ travis-ci = { repository = "awslabs/aws-lambda-rust-runtime" }
maintenance = { status = "actively-developed" }

[dependencies]
base64 = "0.12"
base64 = "0.13.0"
http = "0.2"
lambda = { path = "../lambda", version = "0.1" }
lambda_runtime = { path = "../lambda-runtime", version = "0.1" }
serde = { version = "^1", features = ["derive"] }
serde_json = "^1"
serde_urlencoded = "0.6"
serde_urlencoded = "0.7.0"

[dev-dependencies]
log = "^0.4"
Expand Down
4 changes: 2 additions & 2 deletions lambda-http/examples/hello-http.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use lambda_http::{
handler,
lambda::{self, Context},
lambda_runtime::{self, Context},
IntoResponse, Request, RequestExt, Response,
};

type Error = Box<dyn std::error::Error + Send + Sync + 'static>;

#[tokio::main]
async fn main() -> Result<(), Error> {
lambda::run(handler(func)).await?;
lambda_runtime::run(handler(func)).await?;
Ok(())
}

Expand Down
4 changes: 2 additions & 2 deletions lambda-http/src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ impl Error for PayloadError {
/// as well as `{"x":1, "y":2}` respectively.
///
/// ```rust,no_run
/// use lambda_http::{handler, lambda::{self, Context}, Body, IntoResponse, Request, Response, RequestExt};
/// use lambda_http::{handler, lambda_runtime::{self, Context}, Body, IntoResponse, Request, Response, RequestExt};
/// use serde::Deserialize;
///
/// type Error = Box<dyn std::error::Error + Send + Sync + 'static>;
Expand All @@ -81,7 +81,7 @@ impl Error for PayloadError {
///
/// #[tokio::main]
/// async fn main() -> Result<(), Error> {
/// lambda::run(handler(add)).await?;
/// lambda_runtime::run(handler(add)).await?;
/// Ok(())
/// }
///
Expand Down
20 changes: 10 additions & 10 deletions lambda-http/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@
//! ## Hello World
//!
//! The following example is how you would structure your Lambda such that you have a `main` function where you explicitly invoke
//! `lambda::run` in combination with the [`handler`](fn.handler.html) function. This pattern allows you to utilize global initialization
//! `lambda_runtime::run` in combination with the [`handler`](fn.handler.html) function. This pattern allows you to utilize global initialization
//! of tools such as loggers, to use on warm invokes to the same Lambda function after the first request, helping to reduce the latency of
//! your function's execution path.
//!
//! ```rust,no_run
//! use lambda_http::{handler, lambda};
//! use lambda_http::{handler, lambda_runtime};
//!
//! type Error = Box<dyn std::error::Error + Send + Sync + 'static>;
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Error> {
//! // initialize dependencies once here for the lifetime of your
//! // lambda task
//! lambda::run(handler(|request, context| async { Ok("👋 world!") })).await?;
//! lambda_runtime::run(handler(|request, context| async { Ok("👋 world!") })).await?;
//! Ok(())
//! }
//! ```
Expand All @@ -36,13 +36,13 @@
//! with the [`RequestExt`](trait.RequestExt.html) trait.
//!
//! ```rust,no_run
//! use lambda_http::{handler, lambda::{self, Context}, IntoResponse, Request, RequestExt};
//! use lambda_http::{handler, lambda_runtime::{self, Context}, IntoResponse, Request, RequestExt};
//!
//! type Error = Box<dyn std::error::Error + Send + Sync + 'static>;
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Error> {
//! lambda::run(handler(hello)).await?;
//! lambda_runtime::run(handler(hello)).await?;
//! Ok(())
//! }
//!
Expand All @@ -66,8 +66,8 @@
extern crate maplit;

pub use http::{self, Response};
use lambda::Handler as LambdaHandler;
pub use lambda::{self, Context};
use lambda_runtime::Handler as LambdaHandler;
pub use lambda_runtime::{self, Context};

mod body;
pub mod ext;
Expand All @@ -93,7 +93,7 @@ pub type Request = http::Request<Body>;

/// Functions serving as ALB and API Gateway REST and HTTP API handlers must conform to this type.
///
/// This can be viewed as a `lambda::Handler` constrained to `http` crate `Request` and `Response` types
/// This can be viewed as a `lambda_runtime::Handler` constrained to `http` crate `Request` and `Response` types
pub trait Handler: Sized {
/// The type of Error that this Handler will return
type Error;
Expand All @@ -105,7 +105,7 @@ pub trait Handler: Sized {
fn call(&self, event: Request, context: Context) -> Self::Fut;
}

/// Adapts a [`Handler`](trait.Handler.html) to the `lambda::run` interface
/// Adapts a [`Handler`](trait.Handler.html) to the `lambda_runtime::run` interface
pub fn handler<H: Handler>(handler: H) -> Adapter<H> {
Adapter { handler }
}
Expand Down Expand Up @@ -146,7 +146,7 @@ where
}
}

/// Exists only to satisfy the trait cover rule for `lambda::Handler` impl
/// Exists only to satisfy the trait cover rule for `lambda_runtime::Handler` impl
///
/// User code should never need to interact with this type directly. Since `Adapter` implements `Handler`
/// It serves as a opaque trait covering type.
Expand Down
2 changes: 1 addition & 1 deletion lambda/Cargo.toml → lambda-runtime/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "lambda"
name = "lambda_runtime"
version = "0.1.0"
authors = ["David Barsky <dbarsky@amazon.com>"]
description = "AWS Lambda Runtime"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,6 @@ Runtime.ExitError

See _error-handling.rs_ example for more error handling options.

## macro.rs

The most basic example using `#[lambda]` macro to reduce the amount of boilerplate code.

**Deployment**:
```bash
cp ./target/x86_64-unknown-linux-musl/release/examples/macro ./bootstrap && zip lambda.zip bootstrap && rm bootstrap
Expand Down
4 changes: 2 additions & 2 deletions lambda/examples/basic.rs → lambda-runtime/examples/basic.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// This example requires the following input to succeed:
// { "command": "do something" }

use lambda::{handler_fn, Context};
use lambda_runtime::{handler_fn, Context};
use log::LevelFilter;
use serde::{Deserialize, Serialize};
use simple_logger::SimpleLogger;
Expand Down Expand Up @@ -35,7 +35,7 @@ async fn main() -> Result<(), Error> {
SimpleLogger::new().with_level(LevelFilter::Info).init().unwrap();

let func = handler_fn(my_handler);
lambda::run(func).await?;
lambda_runtime::run(func).await?;
Ok(())
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/// See https://github.com/awslabs/aws-lambda-rust-runtime for more info on Rust runtime for AWS Lambda
use lambda::handler_fn;
use lambda_runtime::handler_fn;
use log::LevelFilter;
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
Expand Down Expand Up @@ -73,12 +73,12 @@ async fn main() -> Result<(), Error> {

// call the actual handler of the request
let func = handler_fn(func);
lambda::run(func).await?;
lambda_runtime::run(func).await?;
Ok(())
}

/// The actual handler of the Lambda request.
pub(crate) async fn func(event: Value, ctx: lambda::Context) -> Result<Value, Error> {
pub(crate) async fn func(event: Value, ctx: lambda_runtime::Context) -> Result<Value, Error> {
// check what action was requested
match serde_json::from_value::<Request>(event)?.event_type {
EventType::SimpleError => {
Expand Down
File renamed without changes.
6 changes: 3 additions & 3 deletions lambda/src/lib.rs → lambda-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! The mechanism available for defining a Lambda function is as follows:
//!
//! Create a type that conforms to the [`Handler`] trait. This type can then be passed
//! to the the `lambda::run` function, which launches and runs the Lambda runtime.
//! to the the `lambda_runtime::run` function, which launches and runs the Lambda runtime.
pub use crate::types::Context;
use client::Client;
use hyper::client::{connect::Connection, HttpConnector};
Expand Down Expand Up @@ -273,15 +273,15 @@ where
///
/// # Example
/// ```no_run
/// use lambda::{handler_fn, Context};
/// use lambda_runtime::{handler_fn, Context};
/// use serde_json::Value;
///
/// type Error = Box<dyn std::error::Error + Send + Sync + 'static>;
///
/// #[tokio::main]
/// async fn main() -> Result<(), Error> {
/// let func = handler_fn(func);
/// lambda::run(func).await?;
/// lambda_runtime::run(func).await?;
/// Ok(())
/// }
///
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.