2.2.0 • Published 3 years ago

custom-lambaa v2.2.0

Weekly downloads
-
License
MIT
Repository
github
Last release
3 years ago

lambaa 🐑

A small framework, with very few dependencies to help build API's using AWS API Gateway & Lambda.

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

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: get

See 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: ""
    }
}
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
        }
    }
}