Mark
Mark

Reputation: 47

Why does this AWS API Gateway Mapping Template not output the correct variable?

I am using AWS API Gateway. I have a response from my backend and I am trying to map the response into a different output using a Mapping Template.

I am trying to return each of the hits.hits._source.display elements. But the mapping template returns the entire object with the literal "_source.display" string added to the end.

The original unmodified server response is like -

{
   "took":7,
   "timed_out":false,
   "_shards":{
      "total":1,
      "successful":1,
      "skipped":0,
      "failed":0
   },
   "hits":{
      "total":{
         "value":10000,
         "relation":"gte"
      },
      "max_score":1.0,
      "hits":[
         {
            "_index":"address",
            "_type":"_doc",
            "_id":"GAVIC411064535",
            "_score":1.0,
            "_source":{
               "id":"GAVIC411064535",
               "display":"1/28 George Street, Casterton VIC 3311",
               "location":{
                  "lat":-37.59205672,
                  "lon":141.38825665
               },
               "component":{
                  "buildingName":"",
                  "number":"1/28",
                  "street":"George Street",
                  "locality":"Casterton",
                  "state":"VIC",
                  "postcode":"3311"
               }
            }
         },
         {
            "_index":"address",
            "_type":"_doc",
            "_id":"GAVIC411066597",
            "_score":1.0,
            "_source":{
               "id":"GAVIC411066597",
               "display":"52 St Georges Road, Corio VIC 3214",
               "location":{
                  "lat":-37.59205672,
                  "lon":141.38825665
               },
               "component":{
                  "buildingName":"",
                  "number":"52",
                  "street":"St Georges Road",
                  "locality":"Corio ",
                  "state":"VIC",
                  "postcode":"3214"
               }
            }
         },

My Mapping Template so far looks like this -

#set($inputRoot = $input.path('$'))
{
#foreach($elem in $inputRoot.hits.hits)
    {
      "address": $elem._source.display,
    }#if($foreach.hasNext),#end
        
#end
}

The resulting output looks like this. You can see that its returing the entire $elem rather than returning the properties I've asked for. That is ._source.display

It has also literally printed ._source.display to the end.

{
  "address": {_index=address, _type=_doc, _id=GAVIC411064535, _score=1.0, _source={id=GAVIC411064535, display=1/28 George Street, Casterton VIC 3311, location={lat=-37.59205672, lon=141.38825665}, component={buildingName=, number=1/28, street=George Street, locality=Casterton, state=VIC, postcode=3311}}}._source.display,
},      
{
  "address": {_index=address, _type=_doc, _id=GAVIC411066597, _score=1.0, _source={id=GAVIC411066597, display=52 St Georges Road, Corio VIC 3214, location={lat=-37.59205672, lon=141.38825665}, component={buildingName=, number=52, street=Georges Road, locality=Corio , state=VIC, postcode=3214}}}._source.display,
},

I have truncated the server response and mapping template output for brevity.

The desired mapping template output is -

{
   "address" : "28 George Street, Casterton VIC 3311",
   "address" : "52 St Georges Road, Corio VIC 3214"
}

Upvotes: 0

Views: 804

Answers (1)

Claude Brisson
Claude Brisson

Reputation: 4130

This is a bug in version 1.7 which has been fixed in 2.x versions (in July 2016... AWS really ought to upgrade its libraries sometimes).

You can work around this bug like this:

#foreach($elem in $inputRoot.hits.hits)
    {
      "address": "$elem.get('_source').display"
    }#if($foreach.hasNext),#end
        
#end

Upvotes: 1

Related Questions