A basic simulator of AWS API Gateway and Lambda runtime, intended to help in developing and debugging Node-based Lambdas for use in AWS from behind API Gateway, both REST and Websockets. All configuration is controlled by a Serverless yaml file.
This was completely rewritten from the ground up. It is wholly incompatible with pre-v2 versions. Apologies to anyone who was using the old one ... but honestly, that wasn't too many of you.
As our development efforts progressed, we increasingly became reliant upon Serverless to control our deployments. It eventually became logical for us to rewrite this module to rely upon serverless.yml to be the single source of truth of our Lambdas.
npm install aws_gw_lambda_simulator
First things first, create a simple serverless.yml file:
# serverless.yml
service: echo_service
provider:
name: aws
runtime: nodejs12.x
functions:
restHandlerFunc:
handler: echo.handler
events:
- http:
path: /
method: getNext, create your barebones scaffold:
// index.js
const API_GW = require('aws_gw_lambda_simulator');
const api_gw = new API_GW('./serverless.yml');
api_gw.serve(({httpPort, wsPort}) => { console.log(`listening http on ${httpPort} and ws on ${wsPort}`); });Finally, create your lambda function. In this case, serverless.yml defines the handler as the handler method in echo.js:
// echo.js
module.exports.handler = (event, context) => {
return {
statusCode:200,
body: JSON.stringify({event, context})
}Start debugging using your favorite editor (ex: Visual Studio Code), and you'll be able to easily set breakpoints and step through your code.
By default, the web service will listen on port 8000.
Instead of - or even in addition to - REST services, aws_gw_lambda_simulator can simulate API Gateway's support for Websockets. Implementing this is as simple as expanding serverless.yml to indicate the websocketsApiRouteSelectionExpression and the handlers.
service: echo_service
provider:
name: aws
runtime: nodejs12.x
# define the property used for auto-routing of websocket messages
websocketsApiRouteSelectionExpression: $request.body.action
functions:
restHandlerFunc:
handler: echo.handler
events:
- http:
path: /
method: get
# define a websocket handler
- websocket:
route: message
routeResponseSelectionExpression: $defaultAPI_GW accepts two parameters:
serverless: a path to aserverless.ymlfile. Required.options: a configuration object. Optional. Ifoptionsmay contain either or both of the following optional properties:-
service: configuration parameters for the service listener. Valid optional parameters include the following.httpPort: The port # to listen on for REST services. Defaults to 8000.wsPort: The port # to listen on for Websocket connections. Defaults to 3000.x_api_key: The value to use to simulate a required API Key. Defaults to an empty string.
-
yaml: parameters to pass into sls-yaml, the parse engine used for readingserverless.yml. Valid optional parameters include the following. See sls-yaml for more information on their meaning.context- See the example for a way of usingcontextto support theoptflag withinserverless.ymlparent
-
To start listening, call api_gw.serve(). This method accepts a single parameter - a callback method that expects an object containing two parameters: httpPort and wsPort. These are the port numbers that the service is listening on for REST and Websockets, respectively. These can be used as follows:
api_gw.serve(({httpPort, wsPort}) => {
console.log(`listening http on ${httpPort} and ws on ${wsPort}`);
});Basic simulation of authorizers is supported for both REST and Websocket connections.
Simply define your authorizer function and reference it as you normally would in serverless.yml. The following code is taken from the included example.
restAuthorizerFunc:
handler: rest-auth.handler
restHandlerFunc:
handler: rest-main.handler
events:
- http:
path: /
method: get
- http:
path: /
method: post
private: true
authorizer:
name: restAuthorizerFunc
identitySource: method.request.header.x-api-key
type: requestSimilarly, simply define your authorizer and onConnect functions and reference them as you normally would in serverless.yml. The following code is taken from the included example.
websocketConnectionHandler:
handler: ws-main.onConnect
events:
- websocket:
route: $connect
routeResponseSelectionExpression: $default
authorizer:
name: websocketAuth
identitySource:
- 'route.request.querystring.code'
websocketAuth:
handler: ws-auth.handler