A deno runtime for AWS Lambda.
Deploy deno code via SAM, serverless, or bundle it yourself.
Define a handler function, for example:
// hello.ts
import {
APIGatewayProxyEvent,
APIGatewayProxyResult,
Context
} from "https://deno.land/x/lambda/mod.ts";
export async function handler(
event: APIGatewayProxyEvent,
context: Context
): Promise<APIGatewayProxyResult> {
return {
statusCode: 200,
body: `Welcome to deno ${Deno.version.deno} 🦕`
};
}
Here the handler is hello.handler
but this can be configured by the Handler
setting.
The following environment variables can be set to change deno-lambda's behavior:
HANDLER_EXT
to set supported extension of handler file e.g.js
orbundle.js
(defaultts
).DENO_CONFIG
so deno runs with--config=$DENO_CONFIG
.DENO_DIR
so deno runs withDENO_DIR=$DENO_DIR deno ...
.DENO_IMPORTMAP
so deno runs with--importmap=$DENO_IMPORTMAP
.DENO_LOCK
so deno runs with--lock=$DENO_LOCK
.DENO_PREFIX
prepends to console.log etc. a template literal, this can includerequestId
andlevel
variables only (default${level}\tRequestId: ${requestId}\r
).
Further configuration TBD.
deno-lambda exports Definitely Typed's aws-lambda types, listed in https://deno.land/x/lambda/mod.ts and defined in https://deno.land/x/lambda/types.d.ts.
It's good practice to reference the trigger's type in the handler, for example:
APIGateway use APIGatewayProxyEvent
and APIGatewayProxyResult
, SQS use SQSEvent
, etc.
The recommended way to deploy is to use the
SAR application
and either reference the outputted LayerArn
as a layer in your function.
- SAR application
- SAM example
- Serverless example (feat. Dynamodb)
- Zipped source example,
deno-lambda-example.zip
, see bundling-code section.
See QUICK-START.md
for a walkthrough of how to bundle yourself.
See the deno_dir-remapping section for how to include the correct DENO_DIR files to avoid any runtime compilation.
The way the lambda platform works means that promises not awaited in the handler may never be completed. This is because the underlying container can be suspended between invocations and will sometimes be shutdown afterwards.
export async function badHandler(
event: APIGatewayProxyEvent,
context: Context
): Promise<APIGatewayProxyResult> {
somethingAsync(); // not awaited so may not complete
return { statusCode: 200, body: "" };
}
export async function goodHandler(
event: APIGatewayProxyEvent,
context: Context
): Promise<APIGatewayProxyResult> {
await somethingAsync();
return { statusCode: 200, body: "" };
}
If you need to return immediately but want to invoke a longer running process you can
async-invoke
another lambda function (that does the await somethingAsync()
).
- deno support for architect
- A layer for AWS Lambda that allows your functions to use
git
andssh
binaries
Create a zip file which contains:
- an entry point which exports an async function (e.g.
hello.ts
) - include any other files needed to run the entry file
- (optional) .deno_dir directory
*You can use a different directory with DENO_DIR
environment variable.
Alternatively use deno bundle
command and include the outputted js file.
In order for compile artifacts to be recovered (and avoid runtime compilation) you must do the following directory remapping:
# Compile the handler (and fetch dependencies into DENO_DIR).
DENO_DIR=.deno_dir deno fetch hello.ts
# This is the "remapping" step:
cp -R .deno_dir/gen/file/$PWD/ .deno_dir/LAMBDA_TASK_ROOT
# Note: We do the inverse of this operation in bootstrap.
zip lambda.zip -x '.deno_dir/gen/file/*' -r .deno_dir hello.ts # other source files
In a serverless.yml
this can be automatically prior to each upload using the
serverless-scriptable-plugin
:
plugins:
- serverless-scriptable-plugin
custom:
scriptHooks:
before:package:createDeploymentArtifacts: DENO_DIR=.deno_dir deno fetch api/candidate.ts && cp -R .deno_dir/gen/file/$PWD/ .deno_dir/LAMBDA_TASK_ROOT
See example-serverless/serverless.yml
.
Many thanks to Yoshiya Hinosawa's blogpost for the initial work on this runtime.