Skip to content

Commit

Permalink
Merge pull request #48 from onicagroup/issue36
Browse files Browse the repository at this point in the history
Issue #36 Upgrade to Middy v1.0
  • Loading branch information
kernwig authored May 14, 2020
2 parents 3011e28 + 7275e2b commit 671f506
Show file tree
Hide file tree
Showing 6 changed files with 7,003 additions and 2,397 deletions.
27 changes: 19 additions & 8 deletions docs/source/lambda_utils.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,11 @@ Used with API Gateway, the included middlewares:
instance will not be destroyed and suffer a cold start on the next invocation.
- Leverages async syntax.

See `Middy middlewares <https://middy.js.org/docs/middlewares.html>`_ for details on those.
See `Middy middlewares <https://middy.js.org/#available-middlewares>`_ for details on those.
Not all Middy middlewares are in this implementation, only common ones that are generally useful in all
APIs. You may extend LambdaUtils's ``wrapApiHandler()`` function in your projects,
or use it as an example to write your own, to add more middleware!

**WARNING**: Middy has, historically, introduced some `breaking changes <https://github.com/onicagroup/sailplane/issues/16>`_
in previous minor version bumps. LambdaUtils has been built and tested with Middy
0.29.0, and should continue to work with future versions, but bumping your
Middy version beyond 0.29.0 may produce some weird errors.


``LambdaUtils`` depends on two other utilities to work:

- :doc:`logger`
Expand All @@ -53,9 +47,26 @@ Middy version beyond 0.29.0 may produce some weird errors.
Install
^^^^^^^

**To use LambdaUtils v3.x with Middy v1.x.x (latest):**

.. code-block:: shell
npm install @sailplane/lambda-utils@3 @sailplane/logger @middy/core @middy/http-cors @middy/http-event-normalizer @middy/http-header-normalizer @middy/http-json-body-parser
The extra @middy/ middleware packages are optional if you write your own wrapper function that does not use them. See below.

**To use LambdaUtils v2.x with Middy v0.x.x:**

.. code-block:: shell
npm install @sailplane/lambda-utils @sailplane/logger middy
npm install @sailplane/lambda-utils@2 @sailplane/logger middy
Upgrading
^^^^^^^^^

To upgrade from lambda-utils v1.x or v2.x to the latest, remove the old with ``npm rm middy``
and then follow the install instructions above to install the latest. See also the
`Middy upgrade instructions <https://middy.js.org/UPGRADE.html>`_.

Examples
^^^^^^^^
Expand Down
22 changes: 8 additions & 14 deletions lambda-utils/lib/lambda-utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ describe("LambdaUtils", () => {

test("wrapApiHandler apiSuccess", (endTest) => {
// GIVEN
const expectResult = { hello: 'world' };

const handler = LambdaUtils.wrapApiHandler(async (event: APIGatewayEvent): Promise<APIGatewayProxyResult> => {
const handler = LambdaUtils.wrapApiHandler(async (event: LambdaUtils.APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
// Echo the event back
return LambdaUtils.apiSuccess(event);
});
Expand Down Expand Up @@ -52,10 +50,10 @@ describe("LambdaUtils", () => {
expect(resultEvent.body).toEqual(body);

// Headers are normalized in request event
expect(resultEvent.headers['content-length']).toBeUndefined();
expect(resultEvent.headers['Content-Length']).toEqual('0');
expect(resultEvent.headers['Content-Length']).toBeUndefined();
expect(resultEvent.headers['content-length']).toEqual('0');
expect(resultEvent.headers["CONTENT-TYPE"]).toBeUndefined();
expect(resultEvent.headers['Content-Type']).toEqual("application/json");
expect(resultEvent.headers['content-type']).toEqual("application/json");

// pathParameters and queryStringParameters are expanded to empty objects
expect(resultEvent.pathParameters).toEqual({});
Expand All @@ -67,9 +65,7 @@ describe("LambdaUtils", () => {

test("wrapApiHandler promise object success", (endTest) => {
// GIVEN
const expectResult = { hello: 'world' };

const handler = LambdaUtils.wrapApiHandler(async (event: APIGatewayEvent): Promise<any> => {
const handler = LambdaUtils.wrapApiHandler(async (): Promise<any> => {
return {message: 'Hello'};
});

Expand Down Expand Up @@ -103,9 +99,7 @@ describe("LambdaUtils", () => {

test("wrapApiHandler promise empty success", (endTest) => {
// GIVEN
const expectResult = { hello: 'world' };

const handler = LambdaUtils.wrapApiHandler(async (event: APIGatewayEvent): Promise<any> => {
const handler = LambdaUtils.wrapApiHandler(async (): Promise<any> => {
return;
});

Expand Down Expand Up @@ -139,7 +133,7 @@ describe("LambdaUtils", () => {

test("wrapApiHandler throw Error", (endTest) => {
// GIVEN
const handler = LambdaUtils.wrapApiHandler(async (event: APIGatewayEvent): Promise<APIGatewayProxyResult> => {
const handler = LambdaUtils.wrapApiHandler(async (): Promise<APIGatewayProxyResult> => {
throw new Error("oops");
});

Expand All @@ -157,7 +151,7 @@ describe("LambdaUtils", () => {

test("wrapApiHandler throw http-error", (endTest) => {
// GIVEN
const handler = LambdaUtils.wrapApiHandler(async (event: APIGatewayEvent): Promise<APIGatewayProxyResult> => {
const handler = LambdaUtils.wrapApiHandler(async (): Promise<APIGatewayProxyResult> => {
throw new createError.NotFound();
});

Expand Down
16 changes: 10 additions & 6 deletions lambda-utils/lib/lambda-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ import {
Context,
ProxyResult
} from "aws-lambda";
import * as middy from "middy";
import {cors, httpEventNormalizer, httpHeaderNormalizer, jsonBodyParser} from "middy/middlewares";

import middy from '@middy/core';
import cors from '@middy/http-cors';
import httpEventNormalizer from '@middy/http-event-normalizer';
import httpHeaderNormalizer from '@middy/http-header-normalizer';
import httpJsonBodyParser from '@middy/http-json-body-parser';
import {Logger} from "@sailplane/logger";

const logger = new Logger('lambda-utils');
Expand Down Expand Up @@ -40,7 +44,7 @@ export type AsyncProxyHandler = (event: APIGatewayProxyEvent, context: Context)
* Fine tuned to work better than the Middy version.
*/
export const unhandledExceptionMiddleware = () => ({
onError: (handler: middy.HandlerLambda<APIGatewayEvent,ProxyResult>, next: middy.NextFunction) => {
onError: (handler: middy.HandlerLambda<APIGatewayEvent, ProxyResult>, next: middy.NextFunction) => {

logger.error('Unhandled exception:', handler.error);

Expand All @@ -62,7 +66,7 @@ export const unhandledExceptionMiddleware = () => ({
* Must be registered as the last (thus first to run) "after" middleware.
*/
export const resolvedPromiseIsSuccessMiddleware = () => ({
after: (handler: middy.HandlerLambda<APIGatewayEvent,ProxyResult>, next: middy.NextFunction) => {
after: (handler: middy.HandlerLambda<APIGatewayEvent, ProxyResult>, next: middy.NextFunction) => {
// If response isn't a proper API result object, convert it into one.
let r = handler.response;
if (!r || typeof r !== 'object' || (!r.statusCode && !r.body)) {
Expand Down Expand Up @@ -96,9 +100,9 @@ export const resolvedPromiseIsSuccessMiddleware = () => ({
* @see https://middy.js.org/docs/middlewares.html
* @see https://www.npmjs.com/package/http-errors
*/
export function wrapApiHandler(handler: AsyncProxyHandler): middy.Middy<APIGatewayEvent,ProxyResult> {
export function wrapApiHandler(handler: AsyncProxyHandler): middy.Middy<AWS_APIGatewayProxyEvent, ProxyResult> {
return middy(handler)
.use(httpEventNormalizer()).use(httpHeaderNormalizer()).use(jsonBodyParser())
.use(httpEventNormalizer()).use(httpHeaderNormalizer()).use(httpJsonBodyParser())
.use(cors())
.use(resolvedPromiseIsSuccessMiddleware())
.use(unhandledExceptionMiddleware());
Expand Down
Loading

0 comments on commit 671f506

Please sign in to comment.