custom-lambaa v2.2.0
lambaa 🐑
A small framework, with very few dependencies to help build API's using AWS API Gateway & Lambda.
Installation
npm i lambaanpm i @types/aws-lambda -DExample Project
Have a look at a Serverless project created using the aws-nodejs-typescript template.
Guide
Controllers
This library has the concept of controllers, similar to other web frameworks.
To create a controller, add the @Controller() decorator to a class and define routes using one of the route decorators, e.g. @GET("/ping").
Currently only API Gateway and SQS events are supported.
import { GET, SQS, Controller } from "lambaa"
import {
    APIGatewayProxyEvent,
    SQSEvent,
    APIGatewayProxyResult,
} from "aws-lambda"
@Controller()
class TestController {
    @GET("/ping")
    public ping(event: APIGatewayProxyEvent): APIGatewayProxyResult {
        // ...
        return {
            statusCode: 200,
            body: "pong",
        }
    }
    @SQS("arn:123")
    public receive(event: SQSEvent): void {
        // ...
        return
    }
}Setup
Create an index.ts file and export the handler.
import { Router } from "lambaa"
const router = new Router({
    controllers: [new PingController()],
})
export const handler = router.getHandler()Use With Serverless (serverless.yml)
Your handler can be referenced in your serverless.yml as follows:
functions:
    ping:
        handler: src/index.handler
    events:
        - http:
              path: ping
              method: getSee the Serverless example project for an example of how to use with
serverless.ts.
Middleware
Middleware can be used to modify the request/response pipeline.
You can define middleware by using the Middleware, or MiddlewareFunction interfaces.
import { MiddlewareFunction } from "lambaa"
const middleware: MiddlewareFunction = async (event, context, next) => {
    // Operate on the request here
    // Pass the event to the next middleware
    const response = await next(event, context)
    // Operate on the response here
    return response
}import { Middleware, Handler } from "lambaa"
import {
    APIGatewayProxyEvent,
    APIGatewayProxyResult,
    Context,
} from "aws-lambda"
class LogRequestMiddleware implements Middleware {
    public async invoke(
        event: APIGatewayProxyEvent,
        context: Context,
        next: Handler
    ): Promise<APIGatewayProxyResult> {
        console.log(
            `Received request - method: ${event.httpMethod}, resource: ${event.resource}`
        )
        const response = await next(event, context)
        return response
    }
}The default middleware event/result types can be changed by specifying generic type parameters.
const sqsMiddleware: MiddlewareFunction<SQSEvent, void> = async (
    event,
    context,
    next
) => {
    // ...
}Applying Middleware
Middleware can be added to a controller method directly, by using the @Use() decorator.
@Use(new AuthenticationMiddleware())
@Use(new LogRequestMiddleware())
@GET("/ping")
public ping(event: APIGatewayProxyEvent) {
    return {
        statusCode: 200,
        body: "pong",
    }
}They can also be applied by being passed to the @Controller() decorator.
@Controller({ middleware: [new LogRequestMiddleware()] })
class PingController {}Finally, they can be applied to many controllers at once, by passing them into the Router constructor.
export const handler = new Router({
    controllers: [new PingController()],
    middleware: [new LogRequestMiddleware()],
}).getHandler()Request Parsing
Parameter decorators can be used to extract the parts of the request which we need.
@GET("/user/{id}")
public getUser(
    @FromHeader("Accept") accept: string,
    @FromPath("id") id: string,
) {
    return {
        statusCode: 200,
        body: ""
    }
}| Function | Description | Type | 
|---|---|---|
| @FromPath() | Extract a path parameter | string | 
| @FromQuery() | Extract a query string parameter | string | 
| @FromBody() | Extract JSON body data | any | 
| @FromHeader() | Extract header value | string | 
Request Parsing Errors
If the required request parameters cannot be found, a RequestError will be thrown.
It is recommended to handle this using a middleware.
class HandleRequestErrorMiddleware implements Middleware {
    public async invoke(
        event: APIGatewayProxyEvent,
        context: Context,
        next: Handler
    ): Promise<APIGatewayProxyResult> {
        try {
            return await next(event, context)
        } catch (err) {
            if (err instanceof RequestError) {
                return {
                    statusCode: 400,
                    body: JSON.stringify({
                        code: err.code,
                    }),
                }
            }
            throw err
        }
    }
}