dbartholomae / lambda-middleware

A collection of middleware for AWS lambda functions.
https://dbartholomae.github.io/lambda-middleware/
MIT License
151 stars 18 forks source link

Help with composeHandler response #50

Closed nateiler closed 3 years ago

nateiler commented 3 years ago

I'm having a hard time determining the return type from a composeHandler. Likely due to a lack TypeScript knowleged.

Everything seems great when using out of the box handlers:

import { ProxyHandler } from "aws-lambda";
import { PromiseHandler } from "@lambda-middleware/utils";
import { composeHandler } from "@lambda-middleware/compose";
import { cors } from "@lambda-middleware/cors";
import { errorHandler } from "@lambda-middleware/http-error-handler";

const helloWorld: PromiseHandler = async () => {
  return {
    body: "Hello World",
    statusCode: 200,
  };
};

export const handler: ProxyHandler = composeHandler(
  errorHandler(),
  cors(),
  helloWorld
);

But with middleware which alter the event, something isn't right:

import {
  ProxyHandler,
  Context,
  APIGatewayProxyEvent,
  APIGatewayProxyResult,
} from "aws-lambda";
import { PromiseHandler } from "@lambda-middleware/utils";
import { composeHandler } from "@lambda-middleware/compose";

const fooMiddleware = () => <E extends APIGatewayProxyEvent>(
  handler: PromiseHandler<E & { foo: string }, APIGatewayProxyResult>
): PromiseHandler<E, APIGatewayProxyResult> => async (
  event: E,
  context: Context
) => {
  return handler({ ...event, foo: "bar" }, context);
};

const barMiddleware = () => <E extends APIGatewayProxyEvent>(
  handler: PromiseHandler<E & { bar: string }, APIGatewayProxyResult>
): PromiseHandler<E, APIGatewayProxyResult> => async (
  event: E,
  context: Context
) => {
  return handler({ ...event, bar: "foo" }, context);
};

const helloWorldEvent = async (
  event: APIGatewayProxyEvent & { foo: string; bar: string }
) => {
  console.log("Foo", event.foo);
  console.log("Bar", event.bar);

  return {
    body: "Hello World",
    statusCode: 200,
  };
};

// Not happy w/ ProxyHandler
export const handler: ProxyHandler = composeHandler(
  fooMiddleware(),
  barMiddleware(),
  helloWorldEvent
);
dbartholomae commented 3 years ago

Unfortunately, this is a limitation of TypeScript related to generics and not solvable by this library. You can find the relevant links and discussions here: https://github.com/dbartholomae/lambda-middleware/issues/36#issuecomment-720755530