Serverless library mimicking AWS Api Gateway for multi query param strings
We use serverless to package our node.js app written in typescript and even though their documentation is extensive, some areas they could have done better.
While serverless is a great convenience, getting it closer to what AWS api gateway offers in terms of functionality or syntax is hard to match, especially when we use offline to mimic api gateway while developing local.
we are developing something and utilized serverless offline feature to test it out locally before pushing it out.
Here is my swagger for AWS api gateway for an GET end point which has path params and multi query params.
endpoint looks like /some-endpoint/abc/def/ghu?flag=abc&flag=def
/some-endpoint/{pathParam1}/{pathParam2}/{pathParam3}:
get:
produces:
- application/json
parameters:
- name: pathParam1
in: path
type: string
required: true
- name: pathParam2
in: path
type: string
required: true
- name: pathParam3
in: path
type: string
required: true
- name: flag
in: query
type: array
required: true
items:
type: string
collectionFormat: multi
responses:
'200':
description: 200 response
and when a post request is formed to a AWS lambda from the gateway, I create request as
requestTemplates:
application/json: |
#set(\$allParams = \$input.params())
{
"body": {
"pathParam1": "\$util.urlDecode(\$util.escapeJavaScript(\$input.params().path.get('pathParam1')))",
"pathParam2": "\$util.urlDecode(\$util.escapeJavaScript(\$input.params().path.get('pathParam2')))",
"pathParam3": "\$util.urlDecode(\$util.escapeJavaScript(\$input.params().path.get('pathParam3')))",
"flags": [
#foreach(\$val in \$method.request.multivaluequerystring.get('flag'))
"\$val"#if(\$foreach.hasNext),#end
#end
]
},
and the request that is made to lambda is as below
{
"pathParam1": "abc",
"pathParam2": "def",
"pathParam3": "ghu",
"flags": ["abc","def"]
}
now while developing locally and testing it out serverless.yml doesn’t follow same syntax as api gateway and their documentation doesn’t spread out all the samples, so after trial and error here is the configuration that worked for me.
functions:
someFunction:
handler: src/handler.handle
description: Retrieve values.
events:
- http:
path: some-endpoint/{pathParam1}/{pathParam2}/{pathParam3}
method: get
integration: lambda
request:
template:
application/json: '{
"body":
{
"pathParam1": "$input.params(''pathParam1'')",
"pathParam2": "$input.params(''pathParam2'')",
"pathParam3": "$input.params(''pathParam3'')",
"flags": [
#foreach($val in $input.params().querystring.get(''flag''))
"$val" #if($foreach.hasNext),#end
#end
]
}
}'
response:
headers:
Content-Type: "'application/json'"
template: $input.path('$.body')
differences is there is no mention of query params or path params and way we access them is different that api gateway and serverless documentation has examples for path params but no examples are found for query strings.
Hope this helps out folks who are trying to do this in their serverless.
Happy serverless computing!