0

How can I store IP, keyword, and other details from OpenSearch response to DynamoDB using AWS AppSync?

I have a setup involving AWS AppSync with OpenSearch and DynamoDB. My objective is to perform a search operation on the OpenSearch data source and then store the searched keyword, IP address, and user agent information into DynamoDB. Below is the schema I'm using:

type Product {
  id: ID!
  code: String
  name: String
  nameAr: String
  platformWeb: Boolean
  country: String
  totalHits: Int
  meta_data: MetaData
}

type MetaData {
  ip: String
  keyword: String
  user_agent: String
}

type Query {
  SearchProduct(
    keyword: String,
    platformWeb: Boolean!,
    country: String!,
    from: Int!
  ): [Brand]

  MetaDataDetails: [MetaData or Product ??]
}

schema {
  query: Query
}

Request Mapping Template for SearchProduct (OpenSearch DataSource)

{
  "version": "2017-02-28",
  "operation": "GET",
  "path": "/my-index-name/_search",
  "params": {
    "body": {
      "from": ${context.arguments.from},
      "size": 24,
      "query": {
        "bool": {
          "must": [
            {
              "bool": {
                "should": [
                  {
                    "match": {
                      "name": {
                        "query": $util.toJson($context.arguments.keyword),
                        "fuzziness": "AUTO",
                        "minimum_should_match": 1,
                        "analyzer": "standard"
                      }
                    }
                  },
                  {
                    "match": {
                      "nameAr": {
                        "query": $util.toJson($context.arguments.keyword),
                        "fuzziness": "AUTO",
                        "minimum_should_match": 1,
                        "analyzer": "standard"
                      }
                    }
                  }
                ]
              }
            }
          ],
          "filter": [
            {
              "term": {
                "country": $util.toJson($context.arguments.country)
              }
            },
            {
              "term": {
                "platformWeb": $util.toJson($context.arguments.platformWeb)
              }
            }
          ]
        }
      }
    }
  }
}

Response Mapping template for SearchProduct

[
   #foreach($entry in $context.result.hits.hits)
        ## $velocityCount starts at 1 and increments with the #foreach loop **
        #if( $velocityCount > 1 ) , #end
        #set( $source = $entry.get("_source"))
        #set( $metaData = {
                "ip": $context.request.headers.x-forwarded-for,
                "keyword": $context.args.keyword,
                "user_agent": $context.request.headers.user-agent
            }
         )
        $util.quiet($source.put("meta_data", $metaData))
        $util.quiet($source.put("totalHits", $ctx.result.hits.total.value))
        $util.toJson($source)
    #end
]

Request Mapping Template for MetaDataDetails (DynamoDB DataSource)

{
    "version": "2018-05-29",
    "operation": "PutItem",
    "key": {
        "item_no": $util.dynamodb.toDynamoDBJson($util.autoId())
    },
    "attributeValues": {
        "ip_address": $util.dynamodb.toDynamoDBJson($context.source.meta_data.ip),
        "search_keyword": $util.dynamodb.toDynamoDBJson($context.source.meta_data.keyword),
        "user_agent": $util.dynamodb.toDynamoDBJson($context.source.meta_data.user_agent)
    }
}

Response Mapping Template for MetaDataDetails

$util.toJson($ctx.result)

I've provided the request and response mapping templates for the SearchProduct operation with the OpenSearch data source and for the MetaDataDetails operation with the DynamoDB data source.

My goal is to execute the following query:

query MyQuery {
  SearchTest(country: "india", from: 0, platformWeb: true, keyword: "hello world") {
    code
    name
    nameAr
    country
    meta_data {
      ip
      keyword
      user_agent
    }
  }
  MetaDataDetails {
    ip
    keyword
    user_agent
  }
}

The issue at hand is that while the SearchTest query is effectively providing all the required values, the MetaDataDetails query is returning null. Upon debugging, I noticed that the $context.source variable is null within the request mapping template of MetaDataDetails. After conducting some initial research, it seems that using $context.prev.result works in pipeline resolvers. However, in my situation, all the operations are conducted within VTL. Is there still a possibility for me to accomplish my intended goal in this scenario?

0 Answers0