Zum Inhalt springen

AWS Lambda ​

AWS Lambda ist eine Serverless-Plattform von Amazon Web Services. Du kannst deinen Code als Reaktion auf Ereignisse ausführen; die zugrunde liegenden Computing-Ressourcen werden automatisch für dich verwaltet.

Hono funktioniert auf AWS Lambda in einer Node.js-18+-Umgebung.

1. Einrichtung ​

Bei der Erstellung einer Anwendung auf AWS Lambda ist CDK nützlich, um Funktionen wie IAM-Rollen, API Gateway und weitere Komponenten einzurichten.

Initialisiere dein Projekt mit der CLI cdk.

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

2. Hello World ​

Bearbeite 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. Bereitstellung ​

Bearbeite lib/my-app-stack.ts.

ts
import * as cdk from 'aws-cdk-lib'
import { Construct } from 'constructs'
import * as lambda from 'aws-cdk-lib/aws-lambda'
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_22_X,
    })
    const fnUrl = fn.addFunctionUrl({
      authType: lambda.FunctionUrlAuthType.NONE,
    })
    new cdk.CfnOutput(this, 'lambdaUrl', {
      value: fnUrl.url!,
    })
  }
}

Führe abschließend den folgenden Befehl zur Bereitstellung aus:

sh
cdk deploy

Binärdaten ausliefern ​

Hono unterstützt Binärdaten als Antwort. In Lambda ist eine Base64-Kodierung erforderlich, um Binärdaten zurückzugeben. Sobald im Header Content-Type ein Binärtyp festgelegt ist, kodiert Hono die Daten automatisch als 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.
})

Auf AWS-Lambda-Objekte zugreifen ​

In Hono kannst du auf AWS-Lambda-Ereignisse und den Kontext zugreifen, indem du die Typen LambdaEvent und LambdaContext bindest und c.env verwendest.

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)

Auf RequestContext zugreifen ​

In Hono kannst du auf den AWS-Lambda-Anfragekontext zugreifen, indem du den Typ LambdaEvent bindest und c.env.event.requestContext verwendest.

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)

Vor v3.10.0 (veraltet) ​

Du kannst auf den AWS-Lambda-Anfragekontext zugreifen, indem du den Typ ApiGatewayRequestContext bindest und c.env. verwendest.

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-Antwortstreaming ​

Durch Ändern des Aufrufmodus von AWS Lambda kannst du Streaming-Antworten ermöglichen.

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

Normalerweise müssen dafür mit awslambda.streamifyResponse Datenblöcke in NodeJS.WritableStream geschrieben werden. Mit dem AWS-Lambda-Adapter kannst du jedoch das gewohnte Antwortstreaming von Hono nutzen, indem du streamHandle statt handle verwendest.

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

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)
    }
  })
})

export const handler = streamHandle(app)

Veröffentlicht unter der MIT-Lizenz.