Skip to content

AWS Lambda

AWS Lambda 是 Amazon Web Services 提供的无服务器平台。你可以运行代码以响应事件并自动为你管理底层计算资源。

¥AWS Lambda is a serverless platform by Amazon Web Services. You can run your code in response to events and automatically manages the underlying compute resources for you.

Hono 在 Node.js 18+ 环境中在 AWS Lambda 上运行。

¥Hono works on AWS Lambda with the Node.js 18+ environment.

1. 设置

¥ Setup

在 AWS Lambda 上创建应用时,CDK 可用于设置 IAM 角色、API 网关等功能。

¥When creating the application on AWS Lambda, CDK is useful to setup the functions such as IAM Role, API Gateway, and others.

使用 cdk CLI 初始化你的项目。

¥Initialize your project with the cdk CLI.

sh
mkdir my-app
cd my-app
cdk init app -l typescript
npm i hono
mkdir lambda
touch lambda/index.ts
sh
mkdir my-app
cd my-app
cdk init app -l typescript
yarn add hono
mkdir lambda
touch lambda/index.ts
sh
mkdir my-app
cd my-app
cdk init app -l typescript
pnpm add hono
mkdir lambda
touch lambda/index.ts
sh
mkdir my-app
cd my-app
cdk init app -l typescript
bun add hono
mkdir lambda
touch lambda/index.ts

2. Hello World

编辑 lambda/index.ts

¥Edit lambda/index.ts.

ts
import { Hono } from 'hono'
import { handle } from 'hono/aws-lambda'

const app = new Hono()

app.get('/', (c) => c.text('Hello Hono!'))

export const handler = handle(app)

3. 部署

¥ Deploy

编辑 lib/cdk-stack.ts

¥Edit lib/cdk-stack.ts.

ts
import * as cdk from 'aws-cdk-lib'
import { Construct } from 'constructs'
import * as lambda from 'aws-cdk-lib/aws-lambda'
import * as apigw from 'aws-cdk-lib/aws-apigateway'
import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs'

export class MyAppStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props)

    const fn = new NodejsFunction(this, 'lambda', {
      entry: 'lambda/index.ts',
      handler: 'handler',
      runtime: lambda.Runtime.NODEJS_20_X,
    })
    fn.addFunctionUrl({
      authType: lambda.FunctionUrlAuthType.NONE,
    })
    new apigw.LambdaRestApi(this, 'myapi', {
      handler: fn,
    })
  }
}

最后,运行命令进行部署:

¥Finally, run the command to deploy:

sh
cdk deploy

提供二进制数据

¥Serve Binary data

Hono 支持二进制数据作为响应。在 Lambda 中,需要使用 base64 编码才能返回二进制数据。将二进制类型设置为 Content-Type 标头后,Hono 会自动将数据编码为 base64。

¥Hono supports binary data as a response. In Lambda, base64 encoding is required to return binary data. Once binary type is set to Content-Type header, Hono automatically encodes data to base64.

ts
app.get('/binary', async (c) => {
  // ...
  c.status(200)
  c.header('Content-Type', 'image/png') // means binary data
  return c.body(buffer) // supports `ArrayBufferLike` type, encoded to base64.
})

访问 AWS Lambda 对象

¥Access AWS Lambda Object

在 Hono 中,你可以通过绑定 LambdaEventLambdaContext 类型并使用 c.env 来访问 AWS Lambda 事件和上下文

¥In Hono, you can access the AWS Lambda Events and Context by binding the LambdaEvent, LambdaContext type and using c.env

ts
import { Hono } from 'hono'
import type { LambdaEvent, LambdaContext } from 'hono/aws-lambda'
import { handle } from 'hono/aws-lambda'

type Bindings = {
  event: LambdaEvent
  lambdaContext: LambdaContext
}

const app = new Hono<{ Bindings: Bindings }>()

app.get('/aws-lambda-info/', (c) => {
  return c.json({
    isBase64Encoded: c.env.event.isBase64Encoded,
    awsRequestId: c.env.lambdaContext.awsRequestId,
  })
})

export const handler = handle(app)

访问 RequestContext

¥Access RequestContext

在 Hono 中,你可以通过绑定 LambdaEvent 类型并使用 c.env.event.requestContext 来访问 AWS Lambda 请求上下文。

¥In Hono, you can access the AWS Lambda request context by binding the LambdaEvent type and using c.env.event.requestContext.

ts
import { Hono } from 'hono'
import type { LambdaEvent } from 'hono/aws-lambda'
import { handle } from 'hono/aws-lambda'

type Bindings = {
  event: LambdaEvent
}

const app = new Hono<{ Bindings: Bindings }>()

app.get('/custom-context/', (c) => {
  const lambdaContext = c.env.event.requestContext
  return c.json(lambdaContext)
})

export const handler = handle(app)

v3.10.0 之前(已弃用)

¥Before v3.10.0 (deprecated)

你可以通过绑定 ApiGatewayRequestContext 类型并使用 c.env. 来访问 AWS Lambda 请求上下文

¥you can access the AWS Lambda request context by binding the ApiGatewayRequestContext type and using c.env.

ts
import { Hono } from 'hono'
import type { ApiGatewayRequestContext } from 'hono/aws-lambda'
import { handle } from 'hono/aws-lambda'

type Bindings = {
  requestContext: ApiGatewayRequestContext
}

const app = new Hono<{ Bindings: Bindings }>()

app.get('/custom-context/', (c) => {
  const lambdaContext = c.env.requestContext
  return c.json(lambdaContext)
})

export const handler = handle(app)

Lambda 响应流

¥Lambda response streaming

通过更改 AWS Lambda 的调用模式,你可以实现 流式响应

¥By changing the invocation mode of AWS Lambda, you can achieve Streaming Response.

diff
fn.addFunctionUrl({
  authType: lambda.FunctionUrlAuthType.NONE,
+  invokeMode: lambda.InvokeMode.RESPONSE_STREAM,
})

通常,实现需要使用 awslambda.streamifyResponse 将块写入 NodeJS.WritableStream,但使用 AWS Lambda Adaptor,你可以使用 streamHandle 而不是 handle 来实现 Hono 的传统流式响应。

¥Typically, the implementation requires writing chunks to NodeJS.WritableStream using awslambda.streamifyResponse, but with the AWS Lambda Adaptor, you can achieve the traditional streaming response of Hono by using streamHandle instead of handle.

ts
import { Hono } from 'hono'
import { streamHandle } from 'hono/aws-lambda'

const app = new Hono()

app.get('/stream', async (c) => {
  return streamText(c, async (stream) => {
    for (let i = 0; i < 3; i++) {
      await stream.writeln(`${i}`)
      await stream.sleep(1)
    }
  })
})

const handler = streamHandle(app)

Hono v4.7 中文网 - 粤ICP备13048890号