# aws-wave

> AWS Lambda Microframework

Latest version **1.2.1** (published 2017-11-06) · MIT license · 0 weekly downloads

## Install

```sh
npm install aws-wave
pnpm add aws-wave
yarn add aws-wave
bun add aws-wave
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.2.1 |
| Published | 2017-11-06 |
| First published | 2017-08-14 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 3 |
| Known vulnerabilities | 0 (+1 in 1 direct dependencies) |
| Install scripts | no |
| GitHub stars | 3 |
| Author | tommelo |
| Maintainers | tom-itgorillaz |
| Keywords | AWS, Lambda, Microframework, Serverless |

## Links

- npm: https://www.npmjs.com/package/aws-wave
- Repository: https://github.com/it-gorillaz/aws-wave
- Homepage: https://github.com/it-gorillaz/aws-wave#readme
- Issues: https://github.com/it-gorillaz/aws-wave/issues
- npm.io page: https://npm.io/package/aws-wave

## Dependencies (3)

- [qs](https://npm.io/package/qs.md) ^6.5.1
- [joi](https://npm.io/package/joi.md) ^10.6.0
- [http-status-codes](https://npm.io/package/http-status-codes.md) ^1.2.0

## Alternatives

- [@opentelemetry/exporter-zipkin](https://npm.io/package/@opentelemetry/exporter-zipkin.md) — 14.8M weekly downloads
- [pusher-js](https://npm.io/package/pusher-js.md) — 2.0M weekly downloads
- [browserify](https://npm.io/package/browserify.md) — 1.7M weekly downloads
- [sqs-consumer](https://npm.io/package/sqs-consumer.md) — 1.7M weekly downloads
- [@sanity/eventsource](https://npm.io/package/@sanity/eventsource.md) — 930.8K weekly downloads

## Recent versions

- 1.2.1 (latest) — 2017-11-06
- 1.2.0 — 2017-11-06
- 1.1.4 — 2017-10-02
- 1.1.3 — 2017-08-30
- 1.1.2 — 2017-08-30
- 1.1.1 — 2017-08-30
- 1.1.0 — 2017-08-30
- 1.0.5 — 2017-08-18
- 1.0.4 — 2017-08-16
- 1.0.3 — 2017-08-14
- 1.0.2 — 2017-08-14
- 1.0.1 — 2017-08-14
- 1.0.0 — 2017-08-14

## README

# aws-wave
AWS Lambda Microframework

## About AWS Wave
AWS Wave is a microframework that makes it easier to develop rest api's using AWS Lambda Functions and API Gateway. It attempts to make the develpment faster by easing common tasks, such as:

 - Exception handling
 - Request body deserialization
 - Response body serialization
 - Request validation
 
## Lambda Proxy Integration

In order to use AWS Wave all methods defined in the API Gateway must use Request Integration Type:```LAMBDA_PROXY```.

A detailed documentation can be found [here](http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html).

## Getting Started

### Instalation

```
npm install aws-wave
```

### Handling Requests

The AWS Wave microframework provides an abstract class called AbstratRequestHandler that handles a Lambda execution call and perform some operations such as request body deserialization, request validation, response body serialization and exception handling.

```javascript
const AbstractRequestHandler = require('aws-wave').AbstractRequestHandler;

class PostUserHandler extends AbstractRequestHandler {
    
    before(event, context) {
      // perform anything before the execution
      this.cors('*');
    }
        
    execute(body, context, callback) {
      callback({ message: 'Hello from aws-wave' });
    }
}

exports.handler = (event, context, callback) => {
  const handler = new PostUserHandler();
  handler.handleRequest(event, context, callback);
}
```

### The Request / Response Attributes
The AbstractRequestHandler class provides methods to access all the request / response attributes and the Lambda environment context as well:

 Attribute                           |                 Method
 -------------------------------- | -----------------------------------------------------
 Request Headers          | getRequestHeader("headerName")
 Response Headers     | addResponseHeader("headerName")
 Raw Request Body     | getRawRequestBody()
 Http Method              | getHttpMethod()
 Resource Path        | getPath()
 Stage Variables          | getStageVariable("stageVariableName")
 Path Parameters          | getPathParameter("parameterName")
 Query String Parameters | getQueryStringParameter("parameterName")
 Request Context Parameter | getRequestContextParameter("parameterName")
 
### Request Validation
AWS Wave uses [Joi](https://github.com/hapijs/joi) to validate requests.
To validate the incoming request a schema should be defined in the class constructor

Eg.:
```javascript
const Joi = require('joi');
const AbstractRequestHandler = require('aws-wave').AbstractRequestHandler;

const schema = Joi.object().keys({
  code: Joi.string().required()  
});

class PhoneConfirmationHandler extends AbstractRequestHandler {
    
    constructor() {
      super(schema);
    }
    
    before(event, context) {     
      this.cors('*');
    }
        
    execute(body, context, callback) {
      callback({ message: 'The request body is valid!' });
    }
}

exports.handler = (event, context, callback) => {
  const handler = new PhoneConfirmationHandler();
  handler.handleRequest(event, context, callback);
}
```

If any constraint violation occurs an UnprocessableEntityException will be thrown and the http response will be serialized with the error details.


Eg.:
```sh
curl -X POST http://my-api-gateway-resource/phone-confirmations -d '{"invalidParam": "value"}'
```
I this particular example the server will respond the above request with a http status code 422 and the following response body:
```json
{
  "message": "Unprocessable entity",
  "errors": [
    {
      "message": "\"code\" is required",
      "path": "code",
      "type": "any.required",
      "context": {
         "key": "code"
      }
    }
  ]
}
```
A detailed documentation of Joi validations can be found [here](https://github.com/hapijs/joi/blob/v10.6.0/API.md).


If you want to provide your own request body validation mechanism, the method *resolveRequestBodyValidator* should be overridden:

```javascript
const Wave = require('aws-wave');

const RequestBodyValidator         = Wave.RequestBodyValidator;
const UnprocessableEntityException = Wave.UnprocessableEntityException;

class MyCustomValidator extends RequestBodyValidator {
  
  validate(entity, schema) {
    // custom validation here
    // should throw a HttpException if any constraint is violated
    throw new UnprocessableEntityException({message: 'Invalid request body'});
  }
  
}

module.exports = MyCustomValidator;
```

```javascript
const MyCustomValidator = require('my-custom-validator');
const AbstractRequestHandler = require('aws-wave').AbstractRequestHandler;

const myCustomSchema = {};

class MyHandler extends AbstractRequestHandler {
    
    constructor() {
      super(myCustomSchema);
    }
    
    before(event, context) {      
      this.cors('*');
    }
        
    execute(body, context, callback) {
      callback({ message: 'The request body is valid!' });
    }
    
    resolveRequestBodyValidator() {
      return new MyCustomValidator();
    }
}

exports.handler = (event, context, callback) => {
  const handler = new MyHandler();
  handler.handleRequest(event, context, callback);
}
```

### Serialization and Deserialization
The current version of AWS Wave supports only JSON serialization/deserialization.

The deserialization and serialization strategies are based on two http headers:

 - **Content-Type** for deserialization
 - **Accept** for serialization

If you want to provide your own request body deserializer, the method *resolveRequestBodyDeserializer* should be overridden:
```javascript
const Wave = require('aws-wave');

const BadRequestException             = Wave.BadRequestException;
const RequestBodyDeserializerStrategy = Wave.RequestBodyDeserializerStrategy;

class MyCustomDeserializer extends RequestBodyDeserializerStrategy {
  
  deserialize(body) {
    // custom deserialization here
    // should throw a HttpException if any error occur
    throw new BadRequestException({message: 'Invalid request body'});
  }
  
}

module.exports = MyCustomDeserializer;
```

If you want to provide your own response body serializer, the method *resolveResponseBodySerializer* should be overridden:
```javascript
const Wave = require('aws-wave');

const InternalServerErrorException    = Wave.InternalServerErrorException;
const RequestBodyDeserializerStrategy = Wave.ResponseBodySerializerStrategy;

class MyCustomSerializer extends ResponseBodySerializerStrategy {
  
  serialize(entity) {
    // custom serialization here
    // should throw a HttpException if any error occur
    throw new InternalServerErrorException({message: 'Unable to serialize the response body'});
  }
  
}

module.exports = MyCustomSerializer;
```

### Exception Handling
AWS Wave offers a built in exception handler, any HttpException will be serialized as response body and any exception not handled will be serialized as an Internal Server Error.

E.g.:

```javascript
const Wave = require('aws-wave');

const AbstractRequestHandler = Wave.AbstractRequestHandler;
const UnauthorizedException  = Wave.UnauthorizedException;

class PostUserHandler extends AbstractRequestHandler {
    
    before(event, context) {      
      this.cors('*');
    }
        
    execute(body, context, callback) {
      // any validation
      if (body.hasPermission)
        return callback(new UnauthorizedException({'The user has no permission'}));
        
      callback({ message: 'The user has permission'});
    }
}

exports.handler = (event, context, callback) => {
  const handler = new PostUserHandler();
  handler.handleRequest(event, context, callback);
}
```

## License
The AWS Wave microframework is open-source software licensed under the [MIT license](https://opensource.org/licenses/MIT) .

---
_Source: https://npm.io/package/aws-wave · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
