-
Notifications
You must be signed in to change notification settings - Fork 13
Description
The most common usage of API GW and Lambda is to configure routes backed by Lambda proxy integrations. Proxy here just means that the whole request that APIGW sees is forwarded to the Lambda function. You can see it's type here
See also https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-api-integration-types.html
My current prototype looks like this:
export type ApiGatewayProxyRequest<
Request extends ApiRequest<any, any, any, any> // targs for path, query string, headers and body
> = Omit<
APIGatewayProxyEvent,
"pathParameters" | "queryStringParameters" | "headers" | "body"
> & {
pathParameters: Request["pathParameters"];
queryStringParameters: Request["queryStringParameters"];
headers: Request["headers"];
body: Request["body"];
};
type ProxyFunction<Request extends ApiRequest<any, any, any, any>> = Function<
ApiGatewayProxyRequest<Request>,
APIGatewayProxyResult
>;
interface ExampleRequest {
pathParameters: {
num: number;
};
}
const httpFn: ProxyFunction<ExampleRequest> = new Function(
stack,
"httpFn",
async (event) => {
return {
statusCode: 200,
body: JSON.stringify({
id: event.pathParameters.num,
}),
};
}
);
const lambdaProxyResource = restApi.root
.addResource("lambda-proxy")
.addResource("{num}");
const lambdaProxyIntegration = ApiIntegrations.lambda({
fn: httpFn,
});
lambdaProxyIntegration.addMethod("GET", lambdaProxyResource);
This gives us parameter types for the Lambda function code to work with.
The problem though is that the body arg API GW sends to Lambda is a string, so the above code won't work. We need some way to preprocess or inject the parsed body into the Lambda input event, or some other mechanism for parsing it while keeping a clean DX.
Some options we discussed:
- Fork
Functioninto a newHttpFunctionclass. The compiler plugin would inject code to parse the body e.g.event = { ...event, body: JSON.parse(event.body) } - Heuristically detect whether a
Functionis backing an api integration and inject code to parse the body - Add ability for user to add middleware into the
Functioncode - Force user to deal with it themselves e.g. add
const body = event.body as BodyTypeto their functions
Middleware option is interesting because it adds value beyond just solving this problem. It is quite common to use middleware for setting up logging, Xray integration etc.
It might look something like this:
new Function(this, "fn", async (event) => event.foo)
.withMiddleware((event) => ({ ...event, body: JSON.parse(body) }))
.withMiddleware((event) => {
XRay.configure(event);
return event;
});