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

Allowing PromiseHandler to have generic Context #49

Closed nateiler closed 3 years ago

nateiler commented 3 years ago

I might be missing something here, but what do you think about adding Context as a generic to the ProxyHandler. I seem to hit a wall when altering it and passing those alterations to the next middleware.

I followed the instructions to creating middleware, but didn't see any references on how to alter the context. As a result, I explored with adding a context generic to the PromiseHandler

New PromiseHandler

export type ContextPromiseHandler<
  TEvent = any,
  TResult = any,
  TContext = Context
> = (event: TEvent, context: TContext) => Promise<TResult>;

And an example of altering the context


// Add `foo` to context
const fooContextMiddleware = () => <
  E extends APIGatewayProxyEvent,
  C extends Context
>(
  handler: ContextPromiseHandler<E, APIGatewayProxyResult, C & { foo: string }>
): ContextPromiseHandler<E, APIGatewayProxyResult, C> => async (
  event: E,
  context: C
) => {
  return handler(event, { ...context, foo: "bar" });
};

// Add `bar` to context
const barContextMiddleware = () => <
  E extends APIGatewayProxyEvent,
  C extends Context
>(
  handler: ContextPromiseHandler<E, APIGatewayProxyResult, C & { bar: string }>
): ContextPromiseHandler<E, APIGatewayProxyResult, C> => async (
  event: E,
  context: C
) => {
  return handler(event, { ...context, bar: "foo" });
};

// Business
const helloWorldContext = async (
  event: APIGatewayProxyEvent,
  context: Context & { foo: string; bar: string }
) => {
  console.log("Foo", context.foo);
  console.log("Bar", context.bar);

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

// In strict mode so using
export const handler = composeHandler(
  fooMiddleware(),
  barMiddleware(),
  helloWorldContext
);
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