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?