@lambda-middleware/compose
Version:
A compose function for functional lambda middleware.
109 lines (89 loc) • 4.01 kB
Markdown
# -middleware/compose
[](https://npmjs.org/package/@lambda-middleware/compose)
[](https://npmjs.org/package/@lambda-middleware/compose)
[](https://github.com/dbartholomae/lambda-middleware/issues)
[](https://github.com/visionmedia/debug#readme)
[](https://github.com/dbartholomae/lambda-middleware/actions?query=workflow%3A.github%2Fworkflows%2Fbuild.yml)
[](https://codecov.io/gh/dbartholomae/lambda-middleware)
[](https://david-dm.org/dbartholomae/lambda-middleware)
[](https://david-dm.org/dbartholomae/lambda-middleware?type=dev)
A compose function for lambda middleware. This is a pure convenience copy of [ramda's compose](https://ramdajs.com/docs/#compose), using it directly or using other compose functions works as well.
## Lambda middleware
This middleware is part of the [lambda middleware series](https://dbartholomae.github.io/lambda-middleware/). It can be used independently.
## Usage
```typescript
import { compose } from "@lambda-middleware/compose";
import { PromiseHandler } from "@lambda-middleware/utils";
import { Context, ProxyHandler, APIGatewayEvent } from "aws-lambda";
// This is your AWS handler
async function helloWorld(): Promise<object> {
return {
message: "Hello world!",
};
}
// Write your own middleware
const stringifyToBody = () => (
handle: PromiseHandler<APIGatewayEvent, object>
) => async (event: APIGatewayEvent, context: Context) => {
const response = await handle(event, context);
return {
body: JSON.stringify(response),
};
};
const addStatusCode = (statusCode: number) => (
handle: PromiseHandler<APIGatewayEvent, { body: string }>
) => async (event: APIGatewayEvent, context: Context) => {
const response = await handle(event, context);
return {
...response,
statusCode,
};
};
// Wrap the handler with the middleware.
// With compose you can wrap multiple middlewares around one handler.
export const handler: ProxyHandler = compose(
addStatusCode(200),
stringifyToBody()
)(helloWorld);
```
## Usage in TypeScript strict mode
There's a [known issue with TypeScript](https://github.com/microsoft/TypeScript/issues/29904) that pipe and compose functions cannot
infer types correctly if the innermost function is generic (in this case the last argument to `compose`).
To get around it, this package also exports `composeHandler`:
```ts
import "reflect-metadata";
import { classValidator } from "@lambda-middleware/class-validator";
import { compose } from "@lambda-middleware/compose";
import { errorHandler } from "@lambda-middleware/http-error-handler";
import { IsString } from "class-validator";
import { APIGatewayProxyResult } from "aws-lambda";
class NameBody {
constructor(firstName: string, lastName: string) {
this.firstName = firstName;
this.lastName = lastName;
}
()
public firstName: string;
()
public lastName: string;
}
async function helloWorld(event: {
body: NameBody;
}): Promise<APIGatewayProxyResult> {
return {
body: `Hello ${event.body.firstName} ${event.body.lastName}`,
headers: {
"content-type": "text",
},
statusCode: 200,
};
}
export const handler = composeHandler(
errorHandler(),
classValidator({
bodyType: NameBody,
}),
// The following function solves the type trouble:
helloWorld
);
```