@ effect-aws/ lambda (英语)
使用 WS Lambda 事件函数处理器和 Web 函数服务器的清洁写法 效果。 。 。 .
它提供了一个 LambdaHandler.make 函数 EffectHandler 并返回本地承诺的 Lambda 处理器功能.
实施支持用优雅的关闭来界定全球运行时间层。 最终结果 acquireRelease 在收到关机信号后运行,但须遵守Lambda的清理期限。 在所有失败模式中,光荣的关闭并不得到保证.
安装
npm install --save @effect-aws/lambda
使用量
Lambda 网络函数
Lambda 网络函数 运行正常的 HTTP 服务器。 使用 LambdaWebFunction.layer 带有效果的 HttpRouter 或者说 HttpApi 听Lambda提供的地址:
npm install @effect-aws/lambda effect @effect/platform-node @effect/platform-node-shared
import * as LambdaWebFunction from "@effect-aws/lambda/LambdaWebFunction"
import { NodeRuntime } from "@effect/platform-node"
import { Effect, Layer } from "effect"
import { HttpRouter, HttpServerResponse } from "effect/http"
const Routes = HttpRouter.use((router) =>
router.add("GET", "/", Effect.succeed(HttpServerResponse.text("Hello from Lambda Web Functions!")))
)
HttpRouter.serve(Routes).pipe(
Layer.provide(LambdaWebFunction.layer),
Layer.launch,
NodeRuntime.runMain
)
给第一个API,通过你的 HttpApiBuilder.layer(...) 及其处理层 HttpRouter.serve 替换 Routes。服务器支持正常的HTTP响应流和并行请求。 在Effect 的请求上下文中保持特定请求状态,而不是共享可变全局.
Web 函数支持通过 @effect-aws/lambda/LambdaWebFunction 子路径。 它需要可选的 @effect/platform-node 端点依赖和相容效果版本( X)@effect/[email protected] 需求 effect@^4.0.0) (中文(简体) ). 现有事件函数用户可以继续从 @effect-aws/lambda 不安装 @effect/platform-node。 。 。 .
LambdaWebFunction.endpoint 读取和验证 AWS_LAMBDA_HTTP_ENDPOINT 使用效果 ConfigProvider失败 ConfigError;没有隐含的收听地址倒置. 指定本地运行 :
AWS_LAMBDA_HTTP_ENDPOINT=127.0.0.1:3000 node index.js
编译或捆绑您的切入点 index.js ,包括运行时间依赖。 关于无害环境管理的产出,包括a package.json 与 "type": "module". Web函数在发射时使用Arm64上的Node.js 24. 与网络函数驱动的 AWS CLI 一起部署已准备的目录 :
aws lambda-web deploy --name my-effect-app --code ./dist
Lambda在制作中提供监听地址. 服务器必须在10秒内开始监听. NodeRuntime.runMain 手柄 SIGTERM 并关闭地层范围; 帮助器将 HTTP 请求排出至 500 毫秒, 在 Lambda 的一秒清理窗口内为其他最后敲定者留下时间 。 清净还作是念已.
Web 函数不使用导出 Lambda 事件处理器, 函数 URL RESPONSE_STREAM 配置,或 LambdaHandler.context()。它们的管理 API 属于单独的 @aws-sdk/client-lambda-web SDK软件包,不需要服务HTTP请求.
Lambda 事件函数
LambdaHandler.make, (中文(简体) ), LambdaHandler.fromHttpApi,以及目标事件函数下方的流出适配器,包括API Gateway集成和Lambda函数 URL.
无依赖性 :
import { Effect } from "effect"
import { EffectHandler, LambdaHandler, SNSEvent } from "@effect-aws/lambda"
// Define your effect handler
const myEffectHandler: EffectHandler<SNSEvent, never> = (event, context) => {
// Your effect logic here
return Effect.succeed("Hello, World!")
}
// Create the Lambda handler
export const handler = LambdaHandler.make(myEffectHandler)
有依赖关系的:
import { EffectHandler, LambdaHandler, SNSEvent } from "@effect-aws/lambda"
import * as Logger from "@effect-aws/powertools-logger"
import { Context, Effect, Layer } from "effect"
interface FooService {
bar: () => Effect.Effect<never, never, void>
}
const FooService = Context.Tag<FooService>()
const FooServiceLive = Layer.succeed(
FooService,
FooService.of({ bar: () => Logger.logInfo("Not implemented") })
)
// Define your effect handler with dependencies
const myEffectHandler: EffectHandler<SNSEvent, FooService> = (event, context) =>
Effect.gen(function* () {
yield* Logger.logInfo("Received event", { event, context })
const service = yield* FooService
return yield* service.bar()
})
// Create the global layer
const LambdaLive = Layer.provideMerge(
FooServiceLive,
Logger.DefaultPowerToolsLoggerLayer
)
// Create the Lambda handler
export const handler = LambdaHandler.make({
handler: myEffectHandler,
layer: LambdaLive
})
流线 :
import { S3 } from "@effect-aws/client-s3"
import { Handler, LambdaHandler } from "@effect-aws/lambda"
import { NodeStream } from "@effect/platform-node"
import { Cause, Effect, Stream } from "effect"
import { Readable } from "node:stream"
import { createGzip } from "node:zlib"
/**
* Streaming handler that reads a file from S3, compresses it using gzip, and
* returns the compressed data as a stream.
*/
const streamHandler = () => {
const stream = S3.getObject({
Bucket: "example-bucket",
Key: "file.txt"
}).pipe(
Effect.map((result) =>
NodeStream.fromReadable(
() => result.Body as Readable,
(e) => new Cause.UnknownException(e)
)
),
Stream.unwrap
)
return stream.pipe(
Stream.pipeThroughChannelOrFail(
NodeStream.fromDuplex(
() => createGzip(),
(e) => new Cause.UnknownException(e)
)
)
)
}
export const handler: Handler = LambdaHandler.stream({
handler: streamHandler,
layer: S3.defaultLayer
})
HttpApi 有 Lambda 函数 URL 的流线:
import { LambdaHandler } from "@effect-aws/lambda"
import {
HttpApi,
HttpApiBuilder,
HttpApiEndpoint,
HttpApiGroup,
HttpApiSchema,
HttpServer,
HttpServerResponse
} from "@effect/platform"
import { Effect, Layer, Stream } from "effect"
const encoder = new TextEncoder()
const streamEndpoint = HttpApiEndpoint.get("stream")`/stream`.addSuccess(
HttpApiSchema.Text()
)
const pingEndpoint = HttpApiEndpoint.get("ping")`/ping`.addSuccess(
HttpApiSchema.Text()
)
const group = HttpApiGroup.make("api").add(streamEndpoint).add(pingEndpoint)
const api = HttpApi.make("Api").add(group)
const routes = HttpApiBuilder.group(api, "api", (handlers) =>
handlers
.handle("ping", () => Effect.succeed("pong\n"))
.handleRaw("stream", () =>
Effect.succeed(
HttpServerResponse.stream(
Stream.fromIterable(["chunk 1\n", "chunk 2\n", "done\n"]).pipe(
Stream.map((chunk) => encoder.encode(chunk))
),
{ contentType: "text/plain; charset=utf-8" }
)
)
)
)
const apiLive = HttpApiBuilder.api(api).pipe(Layer.provide(routes))
export const handler = LambdaHandler.streamFromHttpApi(
Layer.mergeAll(apiLive, HttpServer.layerContext)
)
使用 handle 用于正常的策略反应和 handleRaw 用于流线 HttpServerResponse 数值。 必须通过 Lambda 函数 URL 引用 Lambda 并启用响应流 InvokeMode: RESPONSE_STREAM. API Gateway HTTP API集成不支持Lambda响应流.