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

Download history 368/week @ 2024-03-13 475/week @ 2024-03-20 406/week @ 2024-03-27 506/week @ 2024-04-03 351/week @ 2024-04-10 460/week @ 2024-04-17 502/week @ 2024-04-24 430/week @ 2024-05-01 416/week @ 2024-05-08 440/week @ 2024-05-15 505/week @ 2024-05-22 427/week @ 2024-05-29 345/week @ 2024-06-05 360/week @ 2024-06-12 401/week @ 2024-06-19 345/week @ 2024-06-26

每月下载量1,517
22个包中使用(通过lambda_runtime_core

Apache-2.0

51KB
928

Rust运行时用于AWS Lambda

Build Status

此包使您能够轻松运行用Rust编写的AWS Lambda函数。此工作空间包括多个crate

  • 文档 lambda-runtime-client 是Lambda运行时API的客户端SDK。您可能不需要直接使用此crate!
  • 文档 lambda-runtime 是一个库,使您能够轻松在Rust中编写Lambda函数。
  • 文档 lambda-http 是一个库,使您能够轻松在Rust中编写API Gateway代理事件集中的Lambda函数。

示例函数

下面的代码创建了一个简单的函数,该函数接收一个包含greetingname字段的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