AWS Velocity模板如何区分字符串与其他类型及API Gateway映射模板问题
Great question! I've run into this exact issue with VTL templates in API Gateway before—hardcoding quotes around all query parameter values breaks non-string types like numbers, booleans, or multi-value params, leading to invalid JSON. Here's how to properly handle type detection using AWS's built-in VTL utility functions:
The Root Problem
Your original template wraps every parameter value in double quotes, which forces numbers (like ?id=123) to become "123" (a string instead of a number) and booleans (like ?active=true) to become "true" (also a string). JSON parsers will throw errors when expecting a number/boolean but getting a quoted string.
Solution: Type-Aware VTL Template
Replace your existing template with this version, which checks each parameter's type and formats it correctly for JSON:
{ "context": { /* context params */ }, "request": { #foreach($queryParam in $input.params().querystring.keySet()) "$queryParam" : #set($value = $input.params().querystring.get($queryParam)) # Handle multi-value query params (e.g., ?tags=foo&tags=bar) #if($util.isList($value)) [$foreach($item in $value) #if($util.isNumber($item))$item#elseif($util.isBoolean($item))$item.toLowerCase()#else"$util.escapeJavaScript($item)"#end #if($foreach.hasNext),#end $end] # Handle numeric values (no quotes) #elseif($util.isNumber($value)) $value # Handle boolean values (lowercase, no quotes) #elseif($util.isBoolean($value)) $value.toLowerCase() # Handle strings (quoted, escaped) #else "$util.escapeJavaScript($value)" #end # Add comma if not last parameter #if($foreach.hasNext),#end #end } }
Key Details Explained
Let's break down the critical parts:
- Store the value first: We assign
$value = $input.params().querystring.get($queryParam)to avoid redundant calls and make the template cleaner. - Multi-value params: If a query parameter is repeated (e.g.,
?tags=foo&tags=bar),get()returns a list. We wrap this in[]and process each item individually to maintain correct JSON array syntax. - Number detection: Uses
$util.isNumber()to output numeric values without quotes (e.g.,123instead of"123"). - Boolean handling: Uses
$util.isBoolean()and converts the value to lowercase (since URL params might beTRUE/True, but JSON requires lowercasetrue/false). - String escaping: For strings,
$util.escapeJavaScript()handles special characters like double quotes, backslashes, or newlines, preventing invalid JSON syntax.
Testing Tips
Use API Gateway's built-in Test feature to preview the generated request body. Verify:
- Numeric params appear without quotes
- Booleans are lowercase and unquoted
- Multi-value params form valid JSON arrays
- Special characters in strings are properly escaped
内容的提问来源于stack exchange,提问作者ediblecode

