Skip to content

Commit

Permalink
feat(aws-lambda): add support for alb multiValueQueryStringParameters (
Browse files Browse the repository at this point in the history
  • Loading branch information
yiss authored May 20, 2024
1 parent 827cf60 commit a437161
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 6 deletions.
102 changes: 100 additions & 2 deletions runtime_tests/lambda/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,16 @@ describe('AWS Lambda Adapter for Hono', () => {
return c.json(lambdaContext)
})

app.get('/query-params', (c) => {
const queryParams = c.req.query()
return c.json(queryParams)
})

app.get('/multi-query-params', (c) => {
const multiQueryParams = c.req.queries()
return c.json(multiQueryParams)
})

const testCookie1 = {
key: 'id',
value: crypto.randomUUID(),
Expand Down Expand Up @@ -716,7 +726,6 @@ describe('AWS Lambda Adapter for Hono', () => {
expect(albResponse.headers['set-cookie']).toEqual(
[testCookie1.serialized, testCookie2.serialized].join(', ')
)
expect(albResponse.headers['content-type']).toMatch(/^text\/plain/)
expect(albResponse.isBase64Encoded).toBe(false)
})

Expand Down Expand Up @@ -744,7 +753,96 @@ describe('AWS Lambda Adapter for Hono', () => {
expect(albResponse.multiValueHeaders && albResponse.multiValueHeaders['set-cookie']).toEqual(
expect.arrayContaining([testCookie1.serialized, testCookie2.serialized])
)
expect(albResponse.headers['content-type']).toMatch(/^text\/plain/)
expect(albResponse.isBase64Encoded).toBe(false)
})

it('Should handle a GET request and return a 200 response with queryStringParameters (ALBProxyEvent)', async () => {
const albEventDefaultHeaders = {
resource: '/query-params',
httpMethod: 'GET',
headers: {
'content-type': 'application/json',
},
queryStringParameters: {
key1: 'value1',
key2: 'value2',
},
path: '/query-params',
body: null,
isBase64Encoded: false,
requestContext: testALBRequestContext,
}

const albResponse = await handler(albEventDefaultHeaders)

expect(albResponse.statusCode).toBe(200)
expect(albResponse.body).toContain(
JSON.stringify({
key1: 'value1',
key2: 'value2',
})
)
expect(albResponse.headers['content-type']).toMatch(/^application\/json/)
expect(albResponse.isBase64Encoded).toBe(false)
})

it('Should handle a GET request and return a 200 response with single value multiQueryStringParameters (ALBProxyEvent)', async () => {
const albEventDefaultHeaders = {
resource: '/query-params',
httpMethod: 'GET',
multiValueHeaders: {
'content-type': ['application/json'],
},
multiValueQueryStringParameters: {
key1: ['value1'],
key2: ['value2'],
},
path: '/query-params',
body: null,
isBase64Encoded: false,
requestContext: testALBRequestContext,
}

const albResponse = await handler(albEventDefaultHeaders)

expect(albResponse.statusCode).toBe(200)
expect(albResponse.body).toContain(
JSON.stringify({
key1: 'value1',
key2: 'value2',
})
)
expect(albResponse.headers['content-type']).toMatch(/^application\/json/)
expect(albResponse.isBase64Encoded).toBe(false)
})

it('Should handle a GET request and return a 200 response with multi value multiQueryStringParameters (ALBProxyEvent)', async () => {
const albEventDefaultHeaders = {
resource: '/query-params',
httpMethod: 'GET',
multiValueHeaders: {
'content-type': ['application/json'],
},
multiValueQueryStringParameters: {
key1: ['value1'],
key2: ['value2', 'otherValue2'],
},
path: '/multi-query-params',
body: null,
isBase64Encoded: false,
requestContext: testALBRequestContext,
}

const albResponse = await handler(albEventDefaultHeaders)

expect(albResponse.statusCode).toBe(200)
expect(albResponse.body).toContain(
JSON.stringify({
key1: ['value1'],
key2: ['value2', 'otherValue2'],
})
)
expect(albResponse.headers['content-type']).toMatch(/^application\/json/)
expect(albResponse.isBase64Encoded).toBe(false)
})
})
Expand Down
19 changes: 15 additions & 4 deletions src/adapter/aws-lambda/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ export interface ALBProxyEvent {
body: string | null
isBase64Encoded: boolean
queryStringParameters?: Record<string, string | undefined>
multiValueQueryStringParameters?: {
[parameterKey: string]: string[]
}
requestContext: ALBRequestContext
}

Expand Down Expand Up @@ -406,10 +409,18 @@ const albProcessor = new (class ALBProcessor extends EventProcessor<ALBProxyEven
}

protected getQueryString(event: ALBProxyEvent): string {
return Object.entries(event.queryStringParameters || {})
.filter(([, value]) => value)
.map(([key, value]) => `${key}=${value}`)
.join('&')
// In the case of ALB Integration either queryStringParameters or multiValueQueryStringParameters can be present not both
if (event.queryStringParameters) {
return Object.entries(event.queryStringParameters || {})
.filter(([, value]) => value)
.map(([key, value]) => `${key}=${value}`)
.join('&')
} else {
return Object.entries(event.multiValueQueryStringParameters || {})
.filter(([, value]) => value)
.map(([key, value]) => `${key}=${value.join(`&${key}=`)}`)
.join('&')
}
}

protected getCookies(event: ALBProxyEvent, headers: Headers): void {
Expand Down

0 comments on commit a437161

Please sign in to comment.