4个版本
0.2.2 | 2019年5月3日 |
---|---|
0.2.1 | 2019年2月27日 |
0.2.0 | 2019年1月25日 |
0.1.0 | 2018年11月29日 |
在 网络编程 中排名第2117
每月下载量1,517次
在22个包中使用(通过lambda_runtime_core)
51KB
928 行
Rust运行时用于AWS Lambda
此包使您能够轻松运行用Rust编写的AWS Lambda函数。此工作空间包括多个crate
-
lambda-runtime-client
是Lambda运行时API的客户端SDK。您可能不需要直接使用此crate! -
lambda-runtime
是一个库,使您能够轻松在Rust中编写Lambda函数。 -
lambda-http
是一个库,使您能够轻松在Rust中编写API Gateway代理事件集中的Lambda函数。
示例函数
下面的代码创建了一个简单的函数,该函数接收一个包含greeting
和name
字段的event,并返回一个针对给定名称和问候语的GreetingResponse
消息。注意:要运行这些示例,我们要求Rust版本至少为1.31。
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(())
}
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");
}
Ok(CustomOutput {
message: format!("Hello, {}!", e.first_name),
})
}
上面的代码与lambda-runtime
crate中的基本示例相同。
部署
目前有几种方式构建此包:手动和Serverless 框架。
AWS CLI要使用AWS CLI将基本示例作为 Lambda 函数部署,我们首先需要使用cargo
手动构建它。由于 Lambda 使用 Amazon Linux,你需要将可执行文件针对 x86_64-linux
平台进行编译。
$ cargo build -p lambda_runtime --example basic --release
对于自定义运行时,AWS Lambda 在部署包 zip 文件中寻找名为 bootstrap
的可执行文件。将生成的 basic
可执行文件重命名为 bootstrap
并将其添加到 zip 存档中。
$ cp ./target/release/examples/basic ./bootstrap && zip lambda.zip bootstrap && rm bootstrap
现在我们有了部署包(lambda.zip
),可以使用AWS CLI创建一个新的 Lambda 函数。请确保用您账户中现有的角色替换执行角色!
$ aws lambda create-function --function-name rustTest \
--handler doesnt.matter \
--zip-file file://./lambda.zip \
--runtime provided \
--role arn:aws:iam::XXXXXXXXXXXXX:role/your_lambda_execution_role \
--environment Variables={RUST_BACKTRACE=1} \
--tracing-config Mode=Active
您现在可以使用 AWS CLI 或 AWS Lambda 控制台测试该函数
$ aws lambda invoke --function-name rustTest \
--payload '{"firstName": "world"}' \
output.json
$ cat output.json # Prints: {"message":"Hello, world!"}
Serverless 框架或者,您可以使用Serverless 框架 Rust 插件声明性地构建基于 Rust 的 Lambda 函数。
存在许多入门级 Serverless 应用程序模板,可帮助您快速启动
- 一个最简单的echo 函数,用于演示最小的 Rust 函数设置
- 一个最简单的http 函数,用于演示如何使用 Rust 的原生 http 包与 API Gateway 进行接口(注意这将是直到 0.2 发布的 git 依赖项)
- 一个组合多函数服务,用于演示如何设置包含多个独立函数的服务
假设您的宿主机器有一个相对较新的 node 版本,您不需要安装任何全局的 serverless 依赖项。要开始,运行以下命令创建一个新的 lambda Rust 应用程序并安装项目级依赖项。
$ npx serverless install \
--url https://github.com/softprops/serverless-aws-rust \
--name my-new-app \
&& cd my-new-app \
&& npm install --silent
使用标准的 serverless 工作流程部署它
# build, package, and deploy service to aws lambda
$ npx serverless deploy
使用 serverless 框架或配置的 AWS 集成触发源调用它
$ npx serverless invoke -f hello -d '{"foo":"bar"}'
Docker或者,您可以在AWS Lambda 提供的运行时 docker 映射中构建基于 Rust 的 Lambda 函数,其中预先安装了 Rust 工具链。
运行以下命令将启动一个临时的 docker 容器,该容器将构建您的 Rust 应用程序,并生成一个 zip 文件,其中包含自动重命名为 bootstrap
的二进制文件,以满足 AWS Lambda 对二进制文件的要求,通常这仅仅是您使用 cargo 默认二进制(即 main.rs
)时 crate 的名称
# build and package deploy-ready artifact
$ docker run --rm \
-v ${PWD}:/code \
-v ${HOME}/.cargo/registry:/root/.cargo/registry \
-v ${HOME}/.cargo/git:/root/.cargo/git \
softprops/lambda-rust
在应用程序构建并打包后,它就可以用于生产。您还可以使用lambdaci:提供的 docker 容器本地调用它,以验证其行为,该容器也是 AWS Lambda 提供的运行时的镜像,其中省略了构建依赖项。
# start a docker container replicating the "provided" lambda runtime
# awaiting an event to be provided via stdin
$ unzip -o \
target/lambda/release/{your-binary-name}.zip \
-d /tmp/lambda && \
docker run \
-i -e DOCKER_LAMBDA_USE_STDIN=1 \
--rm \
-v /tmp/lambda:/var/task \
lambci/lambda:provided
# provide an event payload via stdin (typically a json blob)
# Ctrl-D to yield control back to your function
lambda-runtime-client
定义了 RuntimeClient
特性并提供其 HttpRuntimeClient
实现。客户端获取事件并以 Vec<u8>
形式返回输出。
为了向运行时API报告错误,该库定义了RuntimeApiError
特质和ErrorResponse
对象。API的自定义错误应该实现RuntimeApiError
特质的to_response() -> ErrorResponse
方法。
lambda-runtime
这个库使得创建AWS lambda的Rust可执行文件变得容易。该库定义了一个lambda!()
宏。通过主方法调用lambda!()
宏,并传递一个Handler
类型的实现。
pub trait Handler<E, O> {
/// Run the handler.
fn run(
&mut self,
event: E,
ctx: Context
) -> Result<O, HandlerError>;
}
Handler
提供了一个默认实现,允许您向lambda!()
宏提供Rust闭包或函数指针。
可选地,您可以向lambda!()
宏传递您自己的Tokio运行时实例。请参阅我们的with_custom_runtime.rs
示例
AWS事件对象
该项目目前不包括Lambda事件结构体的定义,尽管我们打算在未来这么做。相反,可以使用社区维护的aws_lambda_events
crate来提供强类型化的Lambda事件结构体。您也可以创建自己的自定义事件对象及其对应的结构体。
自定义事件对象
为了序列化和反序列化事件和响应,我们建议使用serde
库。为了接收自定义事件,请使用Serde的宏注解您的结构。
extern crate serde;
extern crate serde_derive;
extern crate serde_json;
use serde_derive::{Serialize, Deserialize};
use serde_json::json;
use std::error::Error;
#[derive(Serialize, Deserialize)]
pub struct NewIceCreamEvent {
pub flavors: Vec<String>,
}
#[derive(Serialize, Deserialize)]
pub struct NewIceCreamResponse {
pub flavors_added_count: usize,
}
fn main() -> Result<(), Box<Error>> {
let flavors = json!({
"flavors": [
"Nocciola",
"抹茶",
"आम"
]
});
let event: NewIceCreamEvent = serde_json::from_value(flavors)?;
let response = NewIceCreamResponse {
flavors_added_count: event.flavors.len(),
};
serde_json::to_string(&response)?;
Ok(())
}
依赖
~11MB
~192K SLoC