All Projects → Albert-Gao → Micro Aws Lambda

Albert-Gao / Micro Aws Lambda

Licence: mit
A 7KB and 0 dependencies AWS Lambda library which supports middleware and easy debug.

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to Micro Aws Lambda

Grant
OAuth Proxy
Stars: ✭ 3,509 (+1838.67%)
Mutual labels:  aws, aws-lambda, lambda, middleware
Lambcycle
🐑🛵 A declarative lambda middleware with life cycle hooks 🐑🛵
Stars: ✭ 88 (-51.38%)
Mutual labels:  aws, aws-lambda, lambda, middleware
Node Athena
a nodejs simple aws athena client
Stars: ✭ 97 (-46.41%)
Mutual labels:  aws, aws-lambda, lambda
Node Lambda Log
Basic logging mechanism for Node 6.10+ Lambda Functions
Stars: ✭ 115 (-36.46%)
Mutual labels:  aws, aws-lambda, lambda
Aws Lambda Wkhtmltopdf
Convert HTML to PDF using Webkit (QtWebKit) on AWS Lambda
Stars: ✭ 165 (-8.84%)
Mutual labels:  aws, aws-lambda, lambda
Serverless Next.js
⚡ Deploy your Next.js apps on AWS Lambda@Edge via Serverless Components
Stars: ✭ 2,977 (+1544.75%)
Mutual labels:  aws, aws-lambda, lambda
Content Lambda Boto3
Automating AWS with Lambda, Python, and Boto3
Stars: ✭ 91 (-49.72%)
Mutual labels:  aws, aws-lambda, lambda
Node Acme Lambda
Use AWS Lambda to manage SSL certificates for ACME providers like Let's Encrypt.
Stars: ✭ 120 (-33.7%)
Mutual labels:  aws, aws-lambda, lambda
Python Lambdarest
Flask like web framework for AWS Lambda
Stars: ✭ 84 (-53.59%)
Mutual labels:  aws, aws-lambda, lambda
Aws Lambda List
A list of hopefully useful AWS lambdas and lambda-related resources.
Stars: ✭ 130 (-28.18%)
Mutual labels:  aws, aws-lambda, lambda
Aws Data Wrangler
Pandas on AWS - Easy integration with Athena, Glue, Redshift, Timestream, QuickSight, Chime, CloudWatchLogs, DynamoDB, EMR, SecretManager, PostgreSQL, MySQL, SQLServer and S3 (Parquet, CSV, JSON and EXCEL).
Stars: ✭ 2,385 (+1217.68%)
Mutual labels:  aws, aws-lambda, lambda
Aws Maintenance Lambda
A lambda function to send alerts (to Slack, HipChat) on AWS maintenance events.
Stars: ✭ 133 (-26.52%)
Mutual labels:  aws, aws-lambda, lambda
Aws Serverless Airline Booking
Airline Booking is a sample web application that provides Flight Search, Flight Payment, Flight Booking and Loyalty points including end-to-end testing, GraphQL and CI/CD. This web application was the theme of Build on Serverless Season 2 on AWS Twitch running from April 24th until end of August in 2019.
Stars: ✭ 1,290 (+612.71%)
Mutual labels:  aws, aws-lambda, lambda
Lambroll
lambroll is a minimal deployment tool for AWS Lambda.
Stars: ✭ 97 (-46.41%)
Mutual labels:  aws, aws-lambda, lambda
Lambda Monitoring
Logging and metrics libraries for AWS Lambda
Stars: ✭ 85 (-53.04%)
Mutual labels:  aws, aws-lambda, lambda
Serverless Layers
Serverless.js plugin that implements AWS Lambda Layers which reduces drastically lambda size, warm-up and deployment time.
Stars: ✭ 119 (-34.25%)
Mutual labels:  aws, aws-lambda, lambda
Serverlessish
Run the same Docker images in AWS Lambda and AWS ECS
Stars: ✭ 177 (-2.21%)
Mutual labels:  aws, aws-lambda, lambda
Lambda Middleware
A collection of middleware for AWS lambda functions.
Stars: ✭ 79 (-56.35%)
Mutual labels:  aws, lambda, middleware
Torchlambda
Lightweight tool to deploy PyTorch models to AWS Lambda
Stars: ✭ 83 (-54.14%)
Mutual labels:  aws, aws-lambda, lambda
Iopipe Js Core
Observe and develop serverless apps with confidence on AWS Lambda with Tracing, Metrics, Profiling, Monitoring, and more.
Stars: ✭ 123 (-32.04%)
Mutual labels:  aws, aws-lambda, lambda

Micro AWS Lambda

Intro

  • For Lambda Proxy / Http API mode
  • Written in Typescript
  • Zero runtime dependencies
  • Tiny: 7KB after minified
  • Rapid middlewares
    • simple reasoning, just running one by one
    • early exit with just throw httpError() or anything
    • pass values among middlewares
  • Return response
    • an object, it will be converted to a Lambda compatible response
    • a customizable httpResponse() / success() (200)
    • a customizable httpError() / badRequest() (400) / internalError() (500)
    • or string, number, boolean
  • Easy debug:
    • Adding debug info to response object
    • console.log event / context

Why do you build this lib

AWS Lambda is making it a flash to creating an API endpoint. But that's just the infrastructure part. It doesn't mean your business logic can be simplified.

  • I need a middleware setup to decouple my business logic without installing a lib that has many dependencies and result in a bigger bundle size as well.
  • I want to deal with a simple interface, where the order is just one by one. I don't want to deal with a mental model where a middleware will be invoked twice for both stages, and handle both the before and after stage in one function.

What problems does it solve

Middleware is for decoupling logic. I learned the value of beforeHooks and afterHooks after adopting Feathers.JS. Which has a beautiful concept of 3 layers for every endpoint, and I found myself start the declarative programming for the backend. No more code for the repeating work. In micro-aws-lambda's context, it is just an array of Middleware.

Let's say a simple return-a-user endpoint, what does it look like when you are using micro-aws-lambda

const handler = lambdas([
  validateRequestBody(GetUserSchema),
  isStillEmployed,
  verifyPaymentStatus,
  justReturnUserObjectDirectlyFromDB,
  removeFieldsFromResponse('password', 'address'),
  combineUserNames,
  transformResponseToClientSideStructure,
]);

Ideally, you can just compose your future lambda without writing any code except for an integration test. The logic will be declarative. Every middleware here can be fully tested and ready to reuse.

Usage

1. Install

npm install micro-aws-lambda

2. Quick start

import { lambdas } from 'micro-aws-lambda';

const handler = lambdas([() => ({ message: 'it works' })]);

// call the API, you will get json response: { message: "it works" }

3. The type of the middleware

type Middleware<PassDownObjType = any, ReturnValueType = any> = ({
  event,
  context,
  passDownObj,
  response,
}: {
  event: APIGatewayProxyEvent; // from @types/aws-lambda
  context: Context; // from @types/aws-lambda
  passDownObj: PlainObject; // for sharing info among middlewares
  readonly response?: any; // for checking the http response
}) => ReturnValueType;

4. Two minutes master

  • How to control the flow?

    • return WON'T stop the execution
    • throw will STOP the execution
    • otherwise, the array of Middleware will just be executed one by one
  • What can you return

    • a httpResponse()
    • or a success() (just a httpResponse() with status code set to 200, you can still change it)
    • or an plain object / string / number (which will be auto-wrapped with success() in the end)
    • Any value returned will be passed to the next middleware as the response parameter
  • What can you throw

    • an httpError()
    • an badRequest()
    • an internalError()
    • or anything else
  • How to check what will be returned as the Http response

    • check the response from the parameter
  • How to change the response

    • you just return a new one in your current middleware
  • How to pass something down the chain,

    • use passDownObj from the parameter
    • attach your value to it: passDownObj.myValue = 123, myValue could be any name
  • Do I have to return something in the middleware

    • No. For example, a validation middleware can only react to the wrong data without returning anything like if (wrong) {}
  • What is the rule of thumb when determine what will be returned is the end?

    • the last returned value always wins.
      • it's simply because you can replace the current response by returning a new one.
    • Which means:
      • if every middleware is returning, the last one wins,
      • if middleware A returns ResponseA, and middleware B is not return anything, ResponseA will be returned (Assume the order is A,B).

5. About the built-in responses

There are 2 types of response:

Built in

  • httpError() for throw
  • httpResponse() for return

Plain JS type

  • return a plain object | string | number === (200) response
  • throw a plain object | string | number === (400) response
  • custom status code by adding statusCode property

The built-in one has some shortcuts to use.

All parameters are customizable.

import { httpError, httpResponse } from 'micro-aws-lambda';

// It gives you an instance of HttpError, which extends from Error
const error = httpError({
  // default status code is 400 if not set
  statusCode: 401,
  body: {
    message: 'test',
  },
  headers: {
    'x-http-header': 'fake-header',
  },
});

// It gives you a plain JS object.
const response = httpResponse({
  // default status code is 200 if not set
  statusCode: 200,
  body: {
    message: 'test',
  },
  headers: {
    'x-http-header': 'fake-header',
  },
});

The commons headers are:

  • 'Access-Control-Allow-Origin': '*',
  • 'Access-Control-Allow-Credentials': true,
  • 'Content-Type': 'application/json',

Supports multiValueHeaders and isBase64Encoded in case you need them.

5.1. Shortcuts

Compare to the above methods, the only difference is the shortcuts just sets the status code, you can still modify them if you want.

  • httpError:
    • badRequest(): 400
    • internalRequest(): 500
  • httpResponse:
    • success(): 200

6. Config

6.1 addTraceInfoToResponse

It will add debug info into the response object

{
  debug: {
    endpoint: "",
    requestBody: "",
    requestMethod: "",

    country: "",
    lambdaRequestId: "",
    logStreamName: "",
    logGroupName: "",
    apiGatewayId: ""
  }
}

6.2 logRequestInfo

It will console.log:

  • event
  • context
  • Aws-Api-Gateway-Request-Id
  • Identity-Source-Ip

7. Examples

7.1 Validation

In the following case, if the request name is 'albert', only validateRequest will be called.

import { badRequest, Middleware } from 'micro-aws-lambda';

const validateRequest: Middleware = ({ event }) => {
  if (event.request.body.name === 'albert') {
    throw badRequest({
      message: 'bad user, bye bye',
    });
  }
};

// it will return a 400 error { message: 'bad user, bye bye' }

Or if you like me, you can write a simple validating middleware with the yup schema, you can then reuse from the client side.

import { Schema } from 'yup';
import { lambdas, Middleware, badRequest } from 'micro-aws-lambda';

const validateBodyWithYupSchema = (schema: Schema): Middleware => async ({
  event,
}) => {
  if (!schema.isValid(event.body)) {
    throw badRequest('bad request');
  }
};

const handler = lambdas([validateBodyWithYupSchema(myYupSchema)]);

7.2 processing Response

import { badRequest } from 'micro-aws-lambda';

const removeFieldsFromResponse = (fieldsToRemove: string[]): Middleware = ({ response }) => {
    const newResponse = Object.assign({}, response);

    fieldsToRemove.forEach(field => {
      if (newResponse[field] != null) {
        delete newResponse[field]
      }
    })

    return newResponse;
};

const testHandler = lambdas(
  [
    () => ({
      name: 'albert',
      password: '123qwe',
      address: 'somewhere on earth'
    }),
    removeFieldsFromResponse(['password', 'address'])
   ],
);

// response will be  { name: 'albert' }

Credits

  • The initial version is heavily inspired by my favourite REST framework: Feathers.JS
  • This project was bootstrapped with TSDX.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].