From 2e79ca8de843ec1b0e4bdda9ec2d0dc2cc27cb18 Mon Sep 17 00:00:00 2001 From: Blake Johnson Date: Mon, 27 Jul 2020 17:52:40 -0700 Subject: [PATCH 1/7] First pass of changes to bring README up to date with `master` branch, preparing for next release --- README.md | 86 ++++++++++++------------------------------------------- 1 file changed, 19 insertions(+), 67 deletions(-) diff --git a/README.md b/README.md index bd8a6d4a..104f7a0b 100644 --- a/README.md +++ b/README.md @@ -2,58 +2,32 @@ This package makes it easy to run AWS Lambda Functions written in Rust. This workspace includes multiple crates: -- [![Docs](https://docs.rs/lambda_runtime_client/badge.svg)](https://docs.rs/lambda_runtime_client) **`lambda-runtime-client`** is a client SDK for the Lambda Runtime APIs. You probably don't need to use this crate directly! -- [![Docs](https://docs.rs/lambda_runtime/badge.svg)](https://docs.rs/lambda_runtime) **`lambda-runtime`** is a library that makes it easy to write Lambda functions in Rust. +- [![Docs](https://docs.rs/lambda/badge.svg)](https://docs.rs/lambda) **`lambda`** is a library that makes it easy to write Lambda functions 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. +- [![Docs](https://docs.rs/lambda_attributes/badge.svg)](https://docs.rs/lambda_attributes) **`lambda-attributes`** holds an [attribute macro](https://doc.rust-lang.org/reference/procedural-macros.html#attribute-macros) that runs an `async main` function in the Lamda runtime. You probably don't need to use this crate directly, the macro is exposed by **`lambda`**! ## Example function -The code below creates a simple function that receives an event with a `greeting` and `name` field and returns a `GreetingResponse` message for the given name and greeting. Notice: to run these examples, we require a minimum Rust version of 1.31. +The code below creates a simple function that receives an event and echoes it back as a response. Notice: to run these examples, we require a minimum Rust version of 1.31. ```rust,no_run -use std::error::Error; - -use lambda_runtime::{error::HandlerError, lambda, Context}; -use log::{self, error}; -use serde_derive::{Deserialize, Serialize}; -use simple_error::bail; -use simple_logger; - -#[derive(Deserialize)] -struct CustomEvent { - #[serde(rename = "firstName")] - first_name: String, -} - -#[derive(Serialize)] -struct CustomOutput { - message: String, -} - -fn main() -> Result<(), Box> { - simple_logger::init_with_level(log::Level::Debug)?; - lambda!(my_handler); - - Ok(()) -} +use lambda::{lambda, Context}; +use serde_json::Value; -fn my_handler(e: CustomEvent, c: Context) -> Result { - if e.first_name == "" { - error!("Empty first name in request {}", c.aws_request_id); - bail!("Empty first name"); - } +type Error = Box; - Ok(CustomOutput { - message: format!("Hello, {}!", e.first_name), - }) +#[lambda] +#[tokio::main] +async fn main(event: Value, _: Context) -> Result { + Ok(event) } ``` -The code above is the same as the [basic example](https://github.com/awslabs/aws-lambda-rust-runtime/tree/master/lambda-runtime/examples/basic.rs) in the `lambda-runtime` crate. +The code above is the same as the [basic example](https://github.com/awslabs/aws-lambda-rust-runtime/tree/master/lambda-runtime/examples/hello.rs) in the `lambda` crate. An [alternative example](https://github.com/awslabs/aws-lambda-rust-runtime/tree/master/lambda-runtime/examples/hello-without-macros.rs) that uses functions instead of an attribute macro to create the handler is available as well. ### Deployment -There are currently multiple ways of building this package: manually, and with the [Serverless framework](https://serverless.com/framework/). +There are currently multiple ways of building this package: manually with the AWS CLI, and with the [Serverless framework](https://serverless.com/framework/). #### AWS CLI @@ -91,9 +65,9 @@ You can now test the function using the AWS CLI or the AWS Lambda console ```bash $ aws lambda invoke --function-name rustTest \ - --payload '{"firstName": "world"}' \ + --payload '{"Hello,": "world!"}' \ output.json -$ cat output.json # Prints: {"message":"Hello, world!"} +$ cat output.json # Prints: {"Hello,": "world!"} ``` **Note:** `--cli-binary-format raw-in-base64-out` is a required @@ -167,34 +141,13 @@ $ unzip -o \ # Ctrl-D to yield control back to your function ``` -## lambda-runtime-client +## `lambda` -Defines the `RuntimeClient` trait and provides its `HttpRuntimeClient` implementation. The client fetches events and returns output as `Vec`. +This library makes it easy to create Rust executables for AWS lambda. The library defines exposes an `#[lambda]` attribute macro. Adding the `#[lambda]` attribute to your `main` function allows you to define your event handler logic in one function as show in the example above. -For error reporting to the runtime APIs the library defines the `RuntimeApiError` trait and the `ErrorResponse` object. Custom errors for the APIs should implement the `to_response() -> ErrorResponse` method of the `RuntimeApiError` trait. +It also exposes the `Handler` trait. A type that conforms to this trait can be passed to the `lambda::run` function, which launches and runs the Lambda runtime. -## lambda-runtime - -This library makes it easy to create Rust executables for AWS lambda. The library defines a `lambda!()` macro. Call the `lambda!()` macro from your main method with an implementation the `Handler` type: - -```rust -pub trait Handler { - /// Run the handler. - fn run( - &mut self, - event: E, - ctx: Context - ) -> Result; -} -``` - -`Handler` provides a default implementation that enables you to provide a Rust closure or function pointer to the `lambda!()` macro. - -Optionally, you can pass your own instance of Tokio runtime to the `lambda!()` macro: -``` -let rt = tokio::runtime::Runtime::new()?; -lambda!(my_handler, rt); -``` +The helper function `handler_fn` provides a default implementation that enables you to provide a Rust closure or function pointer to the `lambda::run` function. ## AWS event objects @@ -206,10 +159,9 @@ To serialize and deserialize events and responses, we suggest using the use the ```rust extern crate serde; -extern crate serde_derive; extern crate serde_json; -use serde_derive::{Serialize, Deserialize}; +use serde::{Serialize, Deserialize}; use serde_json::json; use std::error::Error; From 910c0339cf1db63d3552b78c7d9c56a9fbdcd33d Mon Sep 17 00:00:00 2001 From: Blake Johnson Date: Tue, 28 Jul 2020 10:59:32 -0700 Subject: [PATCH 2/7] First round of PR feedback - address typos and `extern crate` --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index 104f7a0b..50f42265 100644 --- a/README.md +++ b/README.md @@ -143,7 +143,7 @@ $ unzip -o \ ## `lambda` -This library makes it easy to create Rust executables for AWS lambda. The library defines exposes an `#[lambda]` attribute macro. Adding the `#[lambda]` attribute to your `main` function allows you to define your event handler logic in one function as show in the example above. +This library makes it easy to create Rust executables for AWS lambda. The library defines an `#[lambda]` attribute macro. Adding the `#[lambda]` attribute to your `main` function allows you to define your event handler logic in one function as shown in the example above. It also exposes the `Handler` trait. A type that conforms to this trait can be passed to the `lambda::run` function, which launches and runs the Lambda runtime. @@ -158,9 +158,6 @@ This project does not currently include Lambda event struct definitions though w To serialize and deserialize events and responses, we suggest using the use the [`serde`](https://github.com/serde-rs/serde) library. To receive custom events, annotate your structure with Serde's macros: ```rust -extern crate serde; -extern crate serde_json; - use serde::{Serialize, Deserialize}; use serde_json::json; use std::error::Error; From ab460c1733cdbe61f0b9bc70f2dbcd5e3b70eb6c Mon Sep 17 00:00:00 2001 From: Blake Johnson Date: Tue, 28 Jul 2020 21:59:31 -0700 Subject: [PATCH 3/7] Apply suggestions from softprops and davidbarsky Co-authored-by: David Barsky --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 50f42265..e152a2c9 100644 --- a/README.md +++ b/README.md @@ -143,11 +143,14 @@ $ unzip -o \ ## `lambda` -This library makes it easy to create Rust executables for AWS lambda. The library defines an `#[lambda]` attribute macro. Adding the `#[lambda]` attribute to your `main` function allows you to define your event handler logic in one function as shown in the example above. +`lambda` 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`. It also exposes the `Handler` trait. A type that conforms to this trait can be passed to the `lambda::run` function, which launches and runs the Lambda runtime. -The helper function `handler_fn` provides a default implementation that enables you to provide a Rust closure or function pointer to the `lambda::run` function. +The function `handler_fn` converts a rust function or closure to `Handler`, which can then be run by `lambda::run`. ## AWS event objects From 14927a58bc2e07d91ed946066eafa22a4c8c1d87 Mon Sep 17 00:00:00 2001 From: Blake Johnson Date: Tue, 28 Jul 2020 22:08:12 -0700 Subject: [PATCH 4/7] Remove mentions of attribute macro per discussion in PR. --- README.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index e152a2c9..57b60f9e 100644 --- a/README.md +++ b/README.md @@ -4,26 +4,30 @@ This package makes it easy to run AWS Lambda Functions written in Rust. This wor - [![Docs](https://docs.rs/lambda/badge.svg)](https://docs.rs/lambda) **`lambda`** is a library that makes it easy to write Lambda functions 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. -- [![Docs](https://docs.rs/lambda_attributes/badge.svg)](https://docs.rs/lambda_attributes) **`lambda-attributes`** holds an [attribute macro](https://doc.rust-lang.org/reference/procedural-macros.html#attribute-macros) that runs an `async main` function in the Lamda runtime. You probably don't need to use this crate directly, the macro is exposed by **`lambda`**! ## Example function -The code below creates a simple function that receives an event and echoes it back as a response. Notice: to run these examples, we require a minimum Rust version of 1.31. +The code below creates a simple function that receives an event and echoes it back as a response. Notice: this crate is tested against latest stable Rust. ```rust,no_run -use lambda::{lambda, Context}; +use lambda::{handler_fn, Context}; use serde_json::Value; type Error = Box; -#[lambda] #[tokio::main] -async fn main(event: Value, _: Context) -> Result { +async fn main() -> Result<(), Error> { + let func = handler_fn(func); + lambda::run(func).await?; + Ok(()) +} + +async fn func(event: Value, _: Context) -> Result { Ok(event) } ``` -The code above is the same as the [basic example](https://github.com/awslabs/aws-lambda-rust-runtime/tree/master/lambda-runtime/examples/hello.rs) in the `lambda` crate. An [alternative example](https://github.com/awslabs/aws-lambda-rust-runtime/tree/master/lambda-runtime/examples/hello-without-macros.rs) that uses functions instead of an attribute macro to create the handler is available as well. +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. ### Deployment @@ -148,8 +152,6 @@ $ unzip -o \ - `Handler`, a trait that defines interactions between customer-authored code and this library. - `lambda::run`, function that runs an `Handler`. -It also exposes the `Handler` trait. A type that conforms to this trait can be passed to the `lambda::run` function, which launches and runs the Lambda runtime. - The function `handler_fn` converts a rust function or closure to `Handler`, which can then be run by `lambda::run`. ## AWS event objects From 651fbcf2c880f6acc5b9e6931e99c4211e7bd2cc Mon Sep 17 00:00:00 2001 From: Blake Johnson Date: Tue, 28 Jul 2020 22:34:54 -0700 Subject: [PATCH 5/7] Return hello functionality to README and referenced example, while leaving custom object handling to later in the document --- README.md | 8 +++++--- lambda/examples/hello-without-macro.rs | 6 ++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 57b60f9e..4360c16a 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,11 @@ This package makes it easy to run AWS Lambda Functions written in Rust. This wor ## Example function -The code below creates a simple function that receives an event and echoes it back as a response. Notice: this crate is tested against latest stable Rust. +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 serde_json::Value; +use serde_json::{json, Value}; type Error = Box; @@ -23,7 +23,9 @@ async fn main() -> Result<(), Error> { } async fn func(event: Value, _: Context) -> Result { - Ok(event) + let first_name = event["firstName"].as_str().unwrap_or("world"); + + Ok(json!({ "message": format!("Hello, {}!", first_name) })) } ``` diff --git a/lambda/examples/hello-without-macro.rs b/lambda/examples/hello-without-macro.rs index 2aec334f..d94ee322 100644 --- a/lambda/examples/hello-without-macro.rs +++ b/lambda/examples/hello-without-macro.rs @@ -1,5 +1,5 @@ use lambda::{handler_fn, Context}; -use serde_json::Value; +use serde_json::{json, Value}; type Error = Box; @@ -11,5 +11,7 @@ async fn main() -> Result<(), Error> { } async fn func(event: Value, _: Context) -> Result { - Ok(event) + let first_name = event["firstName"].as_str().unwrap_or("world"); + + Ok(json!({ "message": format!("Hello, {}!", first_name) })) } From 5d7a51a8e9a86e5f57b9125a03740b756caaf272 Mon Sep 17 00:00:00 2001 From: Blake Johnson Date: Tue, 28 Jul 2020 22:46:18 -0700 Subject: [PATCH 6/7] Update Deployment to reflect new example behavior --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4360c16a..c86f0ac3 100644 --- a/README.md +++ b/README.md @@ -71,9 +71,9 @@ You can now test the function using the AWS CLI or the AWS Lambda console ```bash $ aws lambda invoke --function-name rustTest \ - --payload '{"Hello,": "world!"}' \ + --payload '{"firstName": "world"}' \ output.json -$ cat output.json # Prints: {"Hello,": "world!"} +$ cat output.json # Prints: {"message": "Hello, world!"} ``` **Note:** `--cli-binary-format raw-in-base64-out` is a required From 5d50e1ca29b20fccaf85074a6904fa4b6ece4f05 Mon Sep 17 00:00:00 2001 From: Blake Johnson Date: Wed, 29 Jul 2020 14:11:29 -0700 Subject: [PATCH 7/7] Suggestion from softprops --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c86f0ac3..8bec6956 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ 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 makes it easy to write Lambda functions in Rust. +- [![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_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