Skip to content

Commit 7448918

Browse files
committed
optional pathParameterUsedAsPath option, fixes #182
1 parent e1ea3c2 commit 7448918

File tree

3 files changed

+106
-4
lines changed

3 files changed

+106
-4
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ $ npm i @fastify/aws-lambda
2929
| decorationPropertyName | The default property name for request decoration | `awsLambda` |
3030
| callbackWaitsForEmptyEventLoop | See: [Official Documentation](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-context.html#nodejs-prog-model-context-properties) | `undefined` |
3131
| retainStage | Retain the stage part of the API Gateway URL | `false` |
32+
| pathParameterUsedAsPath | Use a defined pathParameter as path (i.e. `'proxy'`) | `false` |
3233

3334
## 📖Example
3435

index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ module.exports = (app, options) => {
1616
options.serializeLambdaArguments = options.serializeLambdaArguments !== undefined ? options.serializeLambdaArguments : false
1717
options.decorateRequest = options.decorateRequest !== undefined ? options.decorateRequest : true
1818
options.retainStage = options.retainStage !== undefined ? options.retainStage : false
19+
options.proxiedPathParameterAsPath = options.proxiedPathParameterAsPath !== undefined ? options.proxiedPathParameterAsPath : false
1920
let currentAwsArguments = {}
2021
if (options.decorateRequest) {
2122
options.decorationPropertyName = options.decorationPropertyName || 'awsLambda'
@@ -39,8 +40,7 @@ module.exports = (app, options) => {
3940
event.body = event.body || ''
4041

4142
const method = event.httpMethod || (event.requestContext && event.requestContext.http ? event.requestContext.http.method : undefined)
42-
// NOTE: Use `event.pathParameters.proxy` if available ({proxy+}); fall back to `event.path`
43-
let url = (event.pathParameters && event.pathParameters.proxy && `/${event.pathParameters.proxy}`) || event.path || event.rawPath || '/' // seen rawPath for HTTP-API
43+
let url = (options.pathParameterUsedAsPath && event.pathParameters && event.pathParameters[options.pathParameterUsedAsPath] && `/${event.pathParameters[options.pathParameterUsedAsPath]}`) || event.path || event.rawPath || '/' // seen rawPath for HTTP-API
4444
// NOTE: if used directly via API Gateway domain and /stage
4545
if (!options.retainStage && event.requestContext && event.requestContext.stage &&
4646
event.requestContext.resourcePath && (url).indexOf(`/${event.requestContext.stage}/`) === 0 &&

test/basic.test.js

Lines changed: 103 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ test('proxy in pathParameters with http api', async (t) => {
485485
proxy: 'projects'
486486
}
487487
}
488-
app.get('/projects', async (request, reply) => {
488+
app.get('/prod/projects', async (request, reply) => {
489489
t.equal(request.headers['x-my-header'], 'wuuusaaa')
490490
t.equal(request.headers['user-agent'], 'lightMyRequest')
491491
t.equal(request.headers.host, 'localhost:80')
@@ -505,6 +505,51 @@ test('proxy in pathParameters with http api', async (t) => {
505505
t.equal(ret.headers.connection, 'keep-alive')
506506
})
507507

508+
test('proxy in pathParameters with http api (pathParameterUsedAsPath = "proxy")', async (t) => {
509+
t.plan(13)
510+
511+
const app = fastify()
512+
const evt = {
513+
version: '2.0',
514+
routeKey: 'GET /prod/{proxy+}',
515+
rawPath: '/prod/projects',
516+
rawQueryString: 't=1698604776681',
517+
requestContext: {
518+
http: {
519+
method: 'GET',
520+
path: '/prod/projects'
521+
}
522+
},
523+
headers: {
524+
'X-My-Header': 'wuuusaaa'
525+
},
526+
queryStringParameters: {
527+
t: '1698604776681'
528+
},
529+
pathParameters: {
530+
proxy: 'projects'
531+
}
532+
}
533+
app.get('/projects', async (request, reply) => {
534+
t.equal(request.headers['x-my-header'], 'wuuusaaa')
535+
t.equal(request.headers['user-agent'], 'lightMyRequest')
536+
t.equal(request.headers.host, 'localhost:80')
537+
t.equal(request.headers['content-length'], '0')
538+
t.equal(request.query.t, '1698604776681')
539+
reply.send({ hello: 'world' })
540+
})
541+
const proxy = awsLambdaFastify(app, { pathParameterUsedAsPath: 'proxy' })
542+
const ret = await proxy(evt)
543+
t.equal(ret.statusCode, 200)
544+
t.equal(ret.body, '{"hello":"world"}')
545+
t.equal(ret.isBase64Encoded, false)
546+
t.ok(ret.headers)
547+
t.equal(ret.headers['content-type'], 'application/json; charset=utf-8')
548+
t.equal(ret.headers['content-length'], '17')
549+
t.ok(ret.headers.date)
550+
t.equal(ret.headers.connection, 'keep-alive')
551+
})
552+
508553
test('proxy in pathParameters with rest api', async (t) => {
509554
t.plan(13)
510555

@@ -541,7 +586,7 @@ test('proxy in pathParameters with rest api', async (t) => {
541586
stage: 'dev'
542587
}
543588
}
544-
app.get('/projects', async (request, reply) => {
589+
app.get('/area/projects', async (request, reply) => {
545590
t.equal(request.headers['x-my-header'], 'wuuusaaa')
546591
t.equal(request.headers['user-agent'], 'lightMyRequest')
547592
t.equal(request.headers.host, 'localhost:80')
@@ -560,3 +605,59 @@ test('proxy in pathParameters with rest api', async (t) => {
560605
t.ok(ret.headers.date)
561606
t.equal(ret.headers.connection, 'keep-alive')
562607
})
608+
609+
test('proxy in pathParameters with rest api (pathParameterUsedAsPath = "proxy")', async (t) => {
610+
t.plan(13)
611+
612+
const app = fastify()
613+
const evt = {
614+
resource: '/area/project',
615+
path: '/area/projects',
616+
rawPath: '/prod/projects',
617+
httpMethod: 'GET',
618+
headers: {
619+
'X-My-Header': 'wuuusaaa'
620+
},
621+
multiValueHeaders: {
622+
'X-My-Header': [
623+
'wuuusaaa'
624+
]
625+
},
626+
queryStringParameters: {
627+
t: '1698604776681'
628+
},
629+
multiValueQueryStringParameters: {
630+
t: [
631+
'1698604776681'
632+
]
633+
},
634+
pathParameters: {
635+
proxy: 'projects'
636+
},
637+
stageVariables: null,
638+
requestContext: {
639+
resourcePath: '/area/{proxy+}',
640+
httpMethod: 'GET',
641+
path: '/dev/area/projects',
642+
stage: 'dev'
643+
}
644+
}
645+
app.get('/projects', async (request, reply) => {
646+
t.equal(request.headers['x-my-header'], 'wuuusaaa')
647+
t.equal(request.headers['user-agent'], 'lightMyRequest')
648+
t.equal(request.headers.host, 'localhost:80')
649+
t.equal(request.headers['content-length'], '0')
650+
t.equal(request.query.t, '1698604776681')
651+
reply.send({ hello: 'world' })
652+
})
653+
const proxy = awsLambdaFastify(app, { pathParameterUsedAsPath: 'proxy' })
654+
const ret = await proxy(evt)
655+
t.equal(ret.statusCode, 200)
656+
t.equal(ret.body, '{"hello":"world"}')
657+
t.equal(ret.isBase64Encoded, false)
658+
t.ok(ret.headers)
659+
t.equal(ret.headers['content-type'], 'application/json; charset=utf-8')
660+
t.equal(ret.headers['content-length'], '17')
661+
t.ok(ret.headers.date)
662+
t.equal(ret.headers.connection, 'keep-alive')
663+
})

0 commit comments

Comments
 (0)