Skip to content

Conversation

@svozza
Copy link
Contributor

@svozza svozza commented Nov 5, 2025

Summary

This PR adds support for HTTP API (API Gateway v2) to the event handler utility. It also adds the framework for adding other event sources like function URLs, ALB and VPC lattice.

Edit: after some testing, I've realised that as function URLs and HTTP APIs share the same event type, which means function URLs also work.

Changes

  • The public resolve method now has overloads to support both APIGatewayProxyEvent and APIGatewayProxyEventV2 events. New overloads can be added for new event types. I attempted to do this with conditional types but was unable to make it it work, furthermore, the type signatures were much harder to read than simpler overrides.
  • The #resolve method in the Router class now returns the entire request context object. We use reqCtx.res now as the canonical representation of the response to be returned. As the request is now always represented as a web Response object, converting the response required for different event sources is simpler. We also save the type of response required in the request context using the ResponseType type.
  • The handlerResultToProxyResult function has been removed now that all response are converted to Web Response objects.
  • I have removed the ad hoc base64 encoding functionality. The change to the #resolve method will allow us to handle this is a more principled way by using the request context to indicate whether a response should be encoded or not. I plan to do this work when implementing Feature request: first-class support for binary responses #4514.
  • A new type guard to identify APIGatewayProxyEventV2 objects has been added.
  • A function to convert APIGatewayProxyEventV2 events to Web Request objects has been added.
  • A function to convert Web Respsonse objects to APIGatewayProxyReultV2 objects has been added.

Testing

  • Most of the tests now run using both v1 events and v2 events. The pattern established is easily extended to use additional event types. One suite I have not done so is the middleware tests. These use the exact same mechanisms as the other tests so I have decided to only add some additional v2 specific tests. I am open to persusion as to whether these should follow the other tests.
  • I have used the same lambda function to integrate with an API Gateway REST API and an HTTP API and verified using curl that requests will be fulfilled by the same code with no changes required.
  • Tested a lambda function URL with streaming enabled and it also worked.

Issue number: closes #4713


By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.

@svozza svozza requested review from dreamorosi and sdangol November 5, 2025 15:16
@svozza svozza self-assigned this Nov 5, 2025
@pull-request-size pull-request-size bot added the size/XXL PRs with 1K+ LOC, largely documentation related label Nov 5, 2025
@boring-cyborg boring-cyborg bot added event-handler This item relates to the Event Handler Utility tests PRs that add or change tests labels Nov 5, 2025

describe('Class: Router - Basic Routing', () => {
describe.each([
{ version: 'V1', createEvent: createTestEvent },
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned, these tests can be extended just by adding a new test event creation function to the describe.each block.

* @param stream - The Node.js Readable stream to convert
* @returns A Promise that resolves to a base64 encoded string
*/
async function nodeStreamToBase64(stream: Readable) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will need to add this back when we implement #4514.

@svozza svozza force-pushed the event-handler/http-api-apigwV2 branch from aa81927 to b703896 Compare November 5, 2025 15:28
return {
event,
context,
req: new Request('https://invalid'),
Copy link
Contributor Author

@svozza svozza Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not fond of creating this dummy Request object but the alternative is to make req optional, which will make the ergonomics of writing middleware much worse if users need to do a null check any time they want to interact with a request that will always be there apart from this particular corner case.

it('re-throws non-InvalidHttpMethodError from proxyEventToWebRequest', async () => {
// Prepare
vi.doMock('../../../../src/rest/converters.js', async () => {
const actual = await vi.importActual<
Copy link
Contributor Author

@svozza svozza Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I very much dislike tests like this. The reason we have to do this is because the type guards before this code path are so strict that the error code is virtually unreachable. I have to mock the proxyEventToWebRequest function to throw an exception that it will almost certainly never throw in real use.

@svozza svozza force-pushed the event-handler/http-api-apigwV2 branch 2 times, most recently from 9f3a276 to bc5bdfc Compare November 5, 2025 22:43
sdangol
sdangol previously approved these changes Nov 6, 2025
Copy link
Contributor

@sdangol sdangol left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested it out and looks good

@svozza
Copy link
Contributor Author

svozza commented Nov 6, 2025

Nice!

@svozza svozza force-pushed the event-handler/http-api-apigwV2 branch from 5f2e68e to 21ca074 Compare November 6, 2025 16:29
@sonarqubecloud
Copy link

sonarqubecloud bot commented Nov 6, 2025

@svozza
Copy link
Contributor Author

svozza commented Nov 6, 2025

@swopnildangol I made a change to how we calculate what response to return. Rather than passing the event around and using type guards, I save the response type once in the request context with a type called ResponseType that can only have the value v1 or v2. This allows us to remove a bunch of overloads in the conversion functions and just use conditional types.

@svozza svozza requested a review from sdangol November 6, 2025 16:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

event-handler This item relates to the Event Handler Utility size/XXL PRs with 1K+ LOC, largely documentation related tests PRs that add or change tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: Add support for HTTP APIs (API Gateway v2) in Event Handler

2 participants