-
Notifications
You must be signed in to change notification settings - Fork 361
Bring README up to date with master
branch
#247
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
2e79ca8
910c033
ab460c1
14927a5
651fbcf
5d7a51a
5d50e1c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,58 +2,32 @@ | |
|
||
This package makes it easy to run AWS Lambda Functions written in Rust. This workspace includes multiple crates: | ||
|
||
- [](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! | ||
- [](https://docs.rs/lambda_runtime) **`lambda-runtime`** is a library that makes it easy to write Lambda functions in Rust. | ||
- [](https://docs.rs/lambda) **`lambda`** is a library that makes it easy to write Lambda functions in Rust. | ||
- [](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. | ||
- [](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`**! | ||
voteblake marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## 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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An MSRV of 1.31 is not correct. Right now, it's at least a 1.42_, but I'd for the time being, I'd like to make the policy "latest stable Rust" until this reaches 1.0. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. + 1 (because github markdown) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How does:
sound? |
||
|
||
```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<dyn Error>> { | ||
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<CustomOutput, HandlerError> { | ||
if e.first_name == "" { | ||
error!("Empty first name in request {}", c.aws_request_id); | ||
bail!("Empty first name"); | ||
} | ||
type Error = Box<dyn std::error::Error + Send + Sync + 'static>; | ||
|
||
Ok(CustomOutput { | ||
message: format!("Hello, {}!", e.first_name), | ||
}) | ||
#[lambda] | ||
#[tokio::main] | ||
async fn main(event: Value, _: Context) -> Result<Value, Error> { | ||
Ok(event) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've been thinking about this, but I think we should cut the Let's prefer a more full example? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Interesting, I did not know this about the attribute macro. My primary reason for avoiding it has been more do with developer tooling, I found That type of error (panic on warm invocation) does sound like a reason to hold it back from the release. I can update the README to reflect that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That's another compelling reason to not release and I completely forgot about it. I think the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
this might just be a matter of documentation. I mentioned this in the lambda http docs as a tradeoff to consider. I still think its useful for specific cases but it's also good to be mindful of the tradeoffs. |
||
``` | ||
|
||
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. | ||
voteblake marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### 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/). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's maybe include the SAM CLI with the Makefile approach and (hopefully) aws/aws-lambda-builders#174, once that is merged. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd much more believe in terraform ;d, could add an example with that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I prefer TF too, but if AWS prefers SAM then what most people will use anyway. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
If people adopt SAM as a Rust-lambda "blueprint project", there I'll go too... My current DX fail with Rust lambdas is that I've been unable to find a lightweight and properly documented way to debug Rust lambdas locally... EDIT: this could work for the time being, I guess: https://github.com/rimutaka/lambda-debug-proxy My ideal scenario: not having to deal with docker (i.e: lambci) and my VSCode session having all the variable values, watchpoints and backtraces I would normally have for "regular local binaries", ideally with proper observability all the way down to FFI (C bindgen) crates. Am I dreaming or is this available today and I've missed it? :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Essentially I would like something like this for Rust+SAM+lambdas: https://pawelgrzybek.com/attach-visual-studio-code-debugger-to-sam-serverless-application-model-local-endpoint/ ... does anybody has such a setup? @rimutaka ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @brainstorm, That debug-proxy works for me just fine and I use CLI/TF for deployment. |
||
|
||
#### 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!"} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure I'm in favor of this chance. Can we prefer the original? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've added the previous functionality back to the README and the |
||
``` | ||
|
||
**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<u8>`. | ||
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. | ||
voteblake marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
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. | ||
voteblake marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## 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<E, O> { | ||
/// Run the handler. | ||
fn run( | ||
&mut self, | ||
event: E, | ||
ctx: Context | ||
) -> Result<O, HandlerError>; | ||
} | ||
``` | ||
|
||
`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. | ||
voteblake marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## AWS event objects | ||
|
||
|
@@ -205,11 +158,7 @@ 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_derive; | ||
extern crate serde_json; | ||
|
||
use serde_derive::{Serialize, Deserialize}; | ||
use serde::{Serialize, Deserialize}; | ||
use serde_json::json; | ||
use std::error::Error; | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.