4.2.0 • Published 1 year ago

lambaa v4.2.0

Weekly downloads
24
License
MIT
Repository
github
Last release
1 year ago

lambaa 🐑

A small framework, with very few dependencies to help build applications using AWS Lambda.

Visit vacasaoss.github.io/lambaa for more docs.

Installation

npm i lambaa
npm i @types/aws-lambda -D

Example 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").

import { Controller, GET, POST } from "lambaa"
import { APIGatewayProxyEvent, APIGatewayProxyResult } from "aws-lambda"

@Controller()
class UserController {
    @GET("/user")
    public getUser(event: APIGatewayProxyEvent): APIGatewayProxyResult {}

    @POST("/user")
    public addUser(event: APIGatewayProxyEvent): APIGatewayProxyResult {}
}

Other Supported Events

The following event types are supported in addition to API Gateway events.

FunctionEvent Type
@SQS()SQSEvent
@Schedule()ScheduledEvent
@DynamoDB()DynamoDBStreamEvent
@Kinesis()KinesisStreamEvent
@EventBridge()EventBridgeEvent
@S3()S3Event
@SNS()SNSEvent

See more documentation about the supported event handler decorators here.

Setup

Create an index.ts file and export the handler.

import { Router } from "lambaa"

const router = new Router().registerController(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: get

See the Serverless example project for an example of how to use with serverless.ts.

API Gateway Generic Proxy Resources

Generic proxy resources are also supported using the {proxy+} path variable.

This can simplify the handler setup by allowing you to configure a single event to handle many different HTTP requests.

events:
    - http:
          path: /{proxy+}
          method: ANY

Note: if you choose to use a proxy resource, API Gateway will forward all matching HTTP requests to your Lambda function. This will result in an error if the route is not handled by your application. It is recommended to handle this error using a middleware. Check for the RouterError type.

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 globally using the Router.

export const handler = new Router()
    .registerController(new PingController())
    .registerMiddleware(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: ""
    }
}
FunctionDescriptionType
@FromPath()Extract a path parameterstring
@FromQuery()Extract a query string parameterstring
@FromBody()Extract JSON body dataany
@FromHeader()Extract header valuestring
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
        }
    }
}
4.2.0

1 year ago

4.1.0

2 years ago

3.7.1-alpha.0

2 years ago

3.7.0

2 years ago

3.6.0

2 years ago

4.0.0

2 years ago

4.0.0-next.0

2 years ago

3.4.0

2 years ago

3.5.0

2 years ago

3.4.1-alpha.0

2 years ago

3.3.0

2 years ago

3.2.1

2 years ago

3.2.0

3 years ago

3.1.3

3 years ago

3.1.2

3 years ago

3.1.1

3 years ago

3.1.0

3 years ago

3.0.0

3 years ago

2.2.1

3 years ago

2.2.0

3 years ago

2.1.0

3 years ago

2.0.0

3 years ago

1.3.0

3 years ago

1.2.0

3 years ago

1.1.1

3 years ago

1.1.0

4 years ago

1.0.0

4 years ago