Skip to content

Instantly share code, notes, and snippets.

@timoschinkel
Created August 30, 2022 07:40
Show Gist options
  • Save timoschinkel/f3a6ad5f7e5fff038c60cd624674c8c0 to your computer and use it in GitHub Desktop.
Save timoschinkel/f3a6ad5f7e5fff038c60cd624674c8c0 to your computer and use it in GitHub Desktop.
LambdaMiddleware
import { Context } from 'aws-lambda'; /* npm install @types/aws-lambda */
export interface IMiddleware<E, R> {
process(event: E, context: Context, next: IHandler<E, R>): Promise<R>;
}
export interface IHandler<E, R> {
handle(event: E, context: Context): Promise<R>;
}
export type EventHandler<E, R> = (event: E, context: Context) => Promise<R>;
export class LambdaMiddleware<E, R> {
private readonly middleware: IMiddleware<E, R>[];
constructor(middleware: IMiddleware<E, R>[] = []) {
this.middleware = middleware;
}
public use(middleware: IMiddleware<E, R>): LambdaMiddleware<E, R> {
return new LambdaMiddleware<E, R>([...this.middleware, middleware]);
}
public handle(event: E, context: Context | undefined, handler: EventHandler<E, R>): Promise<R> {
if (this.middleware.length > 0) {
// pass through middleware
const current = this.middleware[0];
return current.process(
event,
context,
{
handle: async (req) => new LambdaMiddleware(this.middleware.slice(1))
.handle(req, context, handler)
}
);
}
return handler(event, context);
}
}
class ObservabilityMiddleware implements IMiddleware<APIGatewayProxyEvent, APIGatewayProxyResult> {
process(event: APIGatewayProxyEvent, context: Context, next: IHandler<APIGatewayProxyEvent, APIGatewayProxyResult>): Promise<APIGatewayProxyResult> {
return next.handle(event, context)
.catch((error: unknown) => {
console.log(error, {
RequestId: context.awsRequestId
});
return {
statusCode: 500,
body: 'Something went horribly wrong!'
};
});
}
}
const handler = new LambdaMiddleware<APIGatewayProxyEvent, APIGatewayProxyResult>()
.use(new ObservabilityMiddleware())
.use({ process: async (event, _, next) =>
next.handle(event, _).then((response) => ({ ...response, headers: { ...response.headers, 'Content-Type': 'application/json' }}))
});
export const MyFunction = async (event: APIGatewayProxyEvent, context: Context): Promise<APIGatewayProxyResult> =>
handler.handle(event, context, async (event: APIGatewayProxyEvent, context: Context | undefined): Promise<APIGatewayProxyResult> => ({
statusCode: 501,
body: 'Not implemented'
}));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment