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
This project abstracts the creation of a basic API and the most commonly desired features.
Provides support for:
- Parameter Validation and Response Generation
- Generation of Swagger Documentation
- Rate Limiting using lambda-rate-limiter
- Logging of ApiErrors using lambda-rollbar
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 asnull
, or if a non-required parameter is not sent, thegetter
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