JSPM

lambda-serverless-api

5.1.1
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 698
  • Score
    100M100P100Q97032F
  • License MIT

Basic Api Wrapper for Serverless Framework.

Package Exports

  • lambda-serverless-api

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (lambda-serverless-api) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Rest Abstraction for Serverless API

Build Status Test Coverage Dependabot Status Dependencies NPM Downloads Semantic-Release Gardener

This project abstracts the creation of a basic API and the most commonly desired features.

Provides support for:

Install

$ npm install --save lambda-serverless-api

Getting Started

First we need to wrap our lambda endpoint. Inside the lambda function we can then use ApiError and JsonResponse as following:

const api = require('lambda-serverless-api').Api({
  limit: 100, // default limit for routes
  limiter: {},
  rollbar: {},
  defaultHeaders: {},
  preflightCheck: () => false,
  preRequestHook: (event, context, rb) => {
    // log or throw error here
  }
});

module.exports = api.wrap('POST register', [
  api.Str('name', 'json', false),
  api.Email('email', 'json'),
  api.Str('password', 'json')
], /* options, */ ({ name = null, email = null, password = null }, context, rb, event) => {
  // handle registration logic here ...
  if (new Date().getHours() === 4) {
    throw api.ApiError('I am a teapot', 418);
  }
  return api.JsonResponse({ message: 'Success!' });
});

where options can contain limit which allows overwrite of limit per endpoint. Rate limiting is explained below.

The first api.wrap parameter defines the route and is re-declared in serverless.yml.

A list of supported parameters can be found here.

If you want to send plain text instead of json, you can use ApiResponse. You can also set custom status codes and headers as second and third parameter respectively.

The defaultHeaders are returned with every request that isn't an unexpected crash. This is handy if you are planning to set up Access headers.

Parameter names are converted to camel case. E.g. X-Custom-Header would be passed as xCustomHeader.

Options

All parameter types support the following options:

options.nullable

Allow input value to be null.
Note: Parameter position must be in [json, context]

Type: boolean

Default: false

Example

/* { "name": null } */
module.exports = api.wrap('POST name', [
  api.Str('name', 'json', false, { nullable: true })
], ({ name }) => {
  console.log(name); // null
});

options.getter

Note: only recommended for advanced use cases.
Optionally asynchronous custom "getting" of variables.
Getter function takes raw input from event, IE a query parameter will always pass String values into the getter function.
Warnings:

  • If used with { nullable: true }, if a rawInput is passed as null, or if a non-required parameter is not sent, the getter function will not be used.
  • Some params (such as Bool, Int, Json, etc) do extra processing after the getter function has returned, and may return inconsistent results. Thorough testing is recommended.

Takes unresolved parameters as second parameter. Simple parameters can be accessed directly, unresolved can be resolved by using await.

Type: Function

Default: null

Example

/* { "name": "  John   "} */
module.exports = api.wrap('POST name', [
  api.Str('name', 'json', true, { getter: (input, params) => input.trim() })
], ({ name }) => {
  console.log(name); // "John"
});

Preflight Requests

When the API is exposed to web clients one needs to deal with preflight "OPTIONS" requests. By default all OPTIONS requests are denied. To customize this one needs to overwrite the preflightCheck option.

An example implementation of this can be found in test/handler.js. The response is expected to be an object on success and otherwise false. The object is expected to contains all headers that should be returned. The parameters passed into the function are origin, allowedMethods, accessControlRequestMethod, accessControlRequestHeaders, path.

Default Headers

Can be defined as a static object, or as a function taking in the request headers. This is e.g. useful for returning the correct origin for cross origin requests with multiple allowed origins.

Note that the request headers are normalized to lower camel case.

Pre Request Hook

Can define a preRequestHook function. This can be used to log events or throw api errors generically.

Takes parameters event (raw lambda function event), context (raw lambda function context) and rb (rollbar logger).

Swagger Documentation

To generate swagger documentation we can call api.generateSwagger() after the api is initialized with routes.

To validate that your swagger documentation matches your serverless.yml you can run api.generateDifference().

Examples can be found here.

Custom Error Messages

You can pass an additional messageId and context to the ApiError constructor. These will be returned with the error response.

Rate Limiting

Rate limiting uses lambda-rate-limiter. Note that there are some serious restrictions because it does not use centralized storage!

To customize rate limiting, the package options are passed as limiter into the constructor.

Logging Api Errors / Exceptions

To monitor api errors and exceptions lambda-rollbar can be enabled. Options are passed by putting them as rollbar into the constructor.

Loading serverless.yml

Consider using yaml-boost

Consider using a single router function instead of declaring each function individually.

Example that also keeps lambda function warm:

functions:
  router:
    handler: lib/handler.router
    events:
      - schedule: rate(10 minutes)
      - http:
          path: /{proxy+}
          method: ANY