aws-sam-cli
aws-sam-cli copied to clipboard
Support --queryStringParameters parameter when generating api gateway aws-proxy event
Describe your idea/feature/enhancement
I want to generate an API GW event to test my lambda locally. My lambda expects queryStringParameters.
I tried:
sam local generate-event apigateway aws-proxy --method GET --path document --body "" --queryStringParameters "{"documentId": "1044", "versionId": "v_1"}"
Error: no such option: --queryStringParameters
Proposal
It's not clear how I can generate an event with custom queryStringParameters. I don't want to edit the json manually if possible.
It would be nice to have some thing like the parameter --queryStringParameters
to make it easy to generate queryStringParameters inside the event.json
@lvthillo Right now, we don't have a better way than generating the event and then editing the output to add the query parameters. This should be something simple to add, would you be interested in contributing it?
@jfuss I was checking in the code base and I don't know if it's really simple. This is samcli/lib/generated_sample_events/events/apigateway/AwsProxy.json
{
"body": "{{{body}}}",
"resource": "{{{resource}}}",
"path": "/{{{path}}}",
"httpMethod": "{{{method}}}",
"isBase64Encoded": true,
"queryStringParameters": {
"foo": "bar"
},
...
As you can see the queryStringParameters value is of type dict and not a string like all the others. So if I understand correctly I can not just update the samcli/lib/generated_sample_events/event-mapping.json and just add:
"querystringparameters": {
"type": "string",
"default": "{"foo": "bar"}"
},
It should be something like (dict and without quotes):
"querystringparameters": {
"type": "dict",
"default": {"foo": "bar"}
},
The output:
samdev local generate-event apigateway aws-proxy --method GET --path document --body "hello"
{'method': 'GET', 'path': 'document', 'body': 'aGVsbG8=', 'stage': 'prod', 'querystringparameters': {'test': 'body'}, 'resource': '/{proxy+}', 'account_id': '123456789012', 'dns_suffix': 'us-east-1.amazonaws.com'}
But here it's substituted as a string
{
"body": "aGVsbG8=",
"resource": "/{proxy+}",
"path": "/document",
"httpMethod": "GET",
"isBase64Encoded": true,
"queryStringParameters": "{'test': 'body'}",
"multiValueQueryStringParameters": {
"foo": [
"bar"
]
},
The 'issue' seems to occur here:
# open the file
with open(file_path) as f:
data = json.load(f)
data = json.dumps(data, indent=2)
# return the substituted file
return renderer.render(data, values_to_sub)
We're passing in the data as JSON but "{"key":"value"}" is a string and not a dict. A (probably not so good) idea could be to check if there are dicts in the values_to_sub
and for each dict replace the json loaded "{"key":"value"}"
with {"key":"value"}
Example:
import chevron
import json
def convert_dicts(data):
updated_data = data
for key, value in values_to_sub.items():
if type(value) is dict:
substitution = "{{{%s}}}" % key
updated_data = updated_data.replace('"%s"' % substitution, substitution)
return updated_data
if __name__== "__main__":
values_to_sub = {'method': 'GET', 'path': 'document', 'body': 'aGVsbG8=', 'stage': 'prod', 'querystringparameters': {'test': 'body'}, 'resource': '/{proxy+}', 'test': {'test': 'jo'}}
data = '''
{
"body": "{{{body}}}",
"resource": "{{{resource}}}",
"path": "/{{{path}}}",
"httpMethod": "{{{method}}}",
"isBase64Encoded": true,
"queryStringParameters": "{{{querystringparameters}}}",
"multiValueQueryStringParameters": {
"foo": [
"bar"
]
},
"test": "{{{test}}}"
}
'''
output = convert_dicts(data)
test = chevron.render(output, values_to_sub)
print(test)
output:
{
"body": "aGVsbG8=",
"resource": "/{proxy+}",
"path": "/document",
"httpMethod": "GET",
"isBase64Encoded": true,
"queryStringParameters": {'test': 'body'},
"multiValueQueryStringParameters": {
"foo": [
"bar"
]
},
"test": {'test': 'jo'}
}