Accessing the GraphQL query from inside an AWS AppSync resolver - terraform-provider-aws

I would like to be able to access the GraphQL query inside of my AWS AppSync resolvers, but have not been able to figure out how to go about achieving this.
I use Terraform to create the resolver, like so:
resource "aws_appsync_resolver" "graphql_event_resolver" {
api_id = aws_appsync_graphql_api.appsync.id
type = "Query"
field = "event"
data_source = aws_appsync_datasource.graphql_datasource.name
request_template = <<EOF
{
"version" : "2017-02-28",
"operation": "Invoke",
"payload": {
"resolve": "event",
"arguments": $util.toJson($context.arguments)
}
}
EOF
response_template = var.response_template
}
Then I have a JavaScript resolver like the one below:
exports.handler = (event, context, callback) => {
console.log('VTL details: ', event);
callback(null, event);
};
I suspect the solution is to pass the query in the request template payload in the Terraform code where I create the resolver, but I have been unable to find any information on how to do this, so any help would be much appreciated.

Figured out, thanks to JWK's answer to this question, how to do it:
resource "aws_appsync_resolver" "graphql_event_resolver" {
api_id = aws_appsync_graphql_api.appsync.id
type = "Query"
field = "event"
data_source = aws_appsync_datasource.graphql_datasource.name
request_template = <<EOF
{
"version" : "2017-02-28",
"operation": "Invoke",
"payload": {
"resolve": "event",
"arguments": $util.toJson($context.arguments),
"query": $utils.toJson($context.info.selectionSetList)
}
}
EOF
response_template = var.response_template
}

Related

Error: Error getting Backup Vault: AccessDeniedException:

Can Someone please help what is this error for? I was configuring AWS Backup and got this error message. I have tried in many ways (IAM policy etc) but no luck. Any assistance is much appreciated.
Error: Error getting Backup Vault: AccessDeniedException:
status code: 403, request id: 501c0713-0ce9-4879-93f6-1887322a38be
I ran into this issue using terraform. I figured this out by adding the "backup-storage:MountCapsule" permission to the policy of the role I am using to create the resource. Here is a slightly edited policy and role configuration. Hopefully, this helps someone.
data "aws_iam_policy_document" "CloudFormationServicePolicy" {
statement {
sid = "AllResources"
effect = "Allow"
actions = [
"backup:*",
"backup-storage:MountCapsule",
...
]
resources = ["*"]
}
statement {
sid = "IAM"
effect = "Allow"
actions = ["iam:PassRole"]
resources = ["*"]
}
}
resource "aws_iam_policy" "CloudFormationServicePolicy" {
name = "${local.resource_name}-CloudFormationServicePolicy"
description = "policy for the IAM role "
path = "/${local.metadata["project"]}/${local.metadata["application"]}/"
policy = data.aws_iam_policy_document.CloudFormationServicePolicy.json
}
resource "aws_iam_role" "CloudFormationServiceRole" {
name = "${local.resource_name}-CloudFormationServiceRole"
description = "Allow cluster to manage node groups, fargate nodes and cloudwatch logs"
force_detach_policies = true
assume_role_policy = jsonencode({
"Version" : "2012-10-17",
"Statement" : [
{
"Action" : "sts:AssumeRole",
"Principal" : {
"Service" : ["cloudformation.amazonaws.com", "ecs-tasks.amazonaws.com"]
},
"Effect" : "Allow",
"Sid" : "TrustStatement"
},
{
"Effect" : "Allow",
"Principal" : {
"AWS" : "arn:aws:iam::xxxxxxx:role/OrganizationAdministratorRole"
},
"Action" : "sts:AssumeRole"
}
]
})
}
resource "aws_iam_role_policy_attachment" "CloudFormationService_task_role_policy_attachment" {
role = aws_iam_role.CloudFormationServiceRole.name
policy_arn = aws_iam_policy.CloudFormationServicePolicy.arn
}

Scan in array of Nested Objects - DynamoDB

So, i am trying to filter objects inside of an array using dynamo db.
This is my sample object
client: {
"name":"etc"
"subscriptions": [
{
"status": "canceled"
... other fields
},
{
"status": "active"
... other fields
}
]
}
I am using filter expressions and dynamoose scan method, what i want to achieve in this case would be the scan bring me back all subscriptions that have the canceled status, is this possible using dynamodb and this kind of objects?.
var filter = {
FilterExpression: "#subscriptions.#status = :statusValue",
ExpressionAttributeNames: {
"#subscriptions":"subscriptions",
"#status": "status"
},
ExpressionAttributeValues:{
":statusValue": "canceled"
}
};
dynamooseEntity.scan(filter).exec();

Get status for a list of items

I have a dynamodb table with a partition key for client_id and no sort key. The json stored in the table just contains the client_id and compliance_level (which is a string title). I need to query the table for a list of client_id's because there is an application that displays client information in a tabular display. I am trying to use ExpressionFilter but get an "Error ValidationException: Either the KeyConditions or KeyConditionExpression parameter must be specified in the request." exception. I don't however have a keycondition to query on. Any assistance would be appreciated. I can't use batchgetitem as there will be more than 100 items to get the status for.
var AWS = require('aws-sdk');
AWS.config.update({region: 'ap-southeast-2'});
var ddb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
var params = {
TableName : "Client-Compliance",
ProjectionExpression: "username, version",
FilterExpression : "client_id IN (:client1, :client2)",
ExpressionAttributeValues : {
":client1" : { "S": "c1234567" },
":client2" : { "S": "c88888888" }
}
};
ddb.query(params, function(err, data) {
if (err) {
console.log("Error", err);
} else {
console.log(data);
}
});
Many thanks

Facing issue while trying to run the updateitem in dynamo db

I am able to fetch the record from dynamo db and view the response successfully. I need to modify the fetched 'ACCOUNTNAME' attribute in the 'items' array and update the json and also update in dynamo db. Now when I try to update the fetched records I end up with the Invalid attribute value type exception.
I was trying to update it using the key with Array of Strings which is provided with code snippet also tried to update inside for loop using the individual string but both failed with same exception as
"statusCode": 400,
"body": {
"message": "Invalid attribute value type",
"error": {
"errorMessage": "ValidationException"
}
}
I tried to create params and update the call inside the for loop by setting the key as below,
Key: {
"UUID": {
"S": usersOfAccountFromDB.body.Items[key].UUID
}
,
"TYPE": {
"S": user
}
}
but also failed with the same exception.
Fetched Json from dynamo db
[
{
"DEFINITION": "914ba44a-8c26-4b60-af0f-96b6aa37efe6",
"UUID": "830a49cb-4ed3-41ae-b111-56714a71ab98",
"TYPE": "USER",
"RELATION": "01efd131-6a5d-4068-889e-9dba44262da5",
"ACCOUNTNAME": "Wolff LLC"
},
{
"DEFINITION": "1f60fded-323d-40e1-a7f8-e2d053b0bed0",
"UUID": "47db3bbe-53ac-4e58-a378-f42331141997",
"TYPE": "USER",
"RELATION": "01efd131-6a5d-4068-889e-9dba44262da5",
"ACCOUNTNAME": "Wolff LLC"
},
{
"DEFINITION": "05ddccba-2b6d-46bd-9db4-7b897ebe16ca",
"UUID": "e7290457-db77-48fc-bd1a-7056bfce8fab",
"TYPE": "USER",
"RELATION": "01efd131-6a5d-4068-889e-9dba44262da5",
"ACCOUNTNAME": "Wolff LLC"
},
.
.
.
.]
Now I tried to iterate the Json and setup UUID which is the key as the String array as below,
var userUUIDArray : string[] = [];
for (let key in usersOfAccountFromDB.body.Items) {
userUUIDArray.push(usersOfAccountFromDB.body.Items[key].UUID);
}
for (var uuid of userUUIDArray) {
console.log("UUID : " +uuid); // prints all the uuid
}
// Creating a parameter for the update dynamo db
var params = {
TableName: <tableName>,
Key: {
"UUID": {
"SS": userUUIDArray
}
,
"TYPE": {
"S": user
}
},
UpdateExpression: 'SET #ACCOUNTNAME = :val1',
ExpressionAttributeNames: {
'#ACCOUNTNAME': 'ACCOUNTNAME' //COLUMN NAME
},
ExpressionAttributeValues: {
':val1': newAccountName
},
ReturnValues: 'UPDATED_NEW',
};
//call the update of dynamodb
const result = await this.getDocClient().update(param).promise();
I get the error as below,
"body": {
"message": "Invalid attribute value type",
"error": {
"errorMessage": "ValidationException"
}
}
All the approaches failed with same above exception
The update operation which your code currently uses only allow a single item to be updated.
IIUC, you want to update multiple items with one API call. For this you need to use batchWrite operation. Keep in mind that you cannot update more than 25 items per invocation.
The origin of the error you are getting
Your code fails due to the use of "SS" in the UUID field. This field is of type string so you must use "S". Note however that since you're using the document client API you do not need to pass values using this notation. See this answer for further details.
I have resolved the issue now by running the update statement one by one using loop
for (let key in usersOfAccountFromDB.body.Items) {
var updateParam = {
TableName: process.env.AWS_DYNAMO_TABLE,
Key: {
UUID: usersOfAccountFromDB.body.Items[key].UUID,
TYPE: user
},
UpdateExpression: "SET #ACCOUNTNAME = :val1",
ExpressionAttributeNames: {
'#ACCOUNTNAME': 'ACCOUNTNAME'
},
ExpressionAttributeValues: {
":val1": newAccountName
},
ReturnValues: "UPDATED_NEW",
};
const result = await this.getDocClient().update(updateParam).promise();
}

AppSync client query not returning complete data response

I am having an issue getting results back from my AppSync API via AWSAppSyncClient. I can run the query in the AWS AppSync console and get the complete results, however when I run the query from my client the portion of the results I am looking for returns an empty array.
I have tried slimming down the query to return less results, as I read at one point that dynamo will run a filter on the results being returned if you do not provide your own. I have also read this could have something to do with the partition keys used in the dynamoDB table, however AppSync provisioned that resource for me and handled the initial config. I am new to working with AppSync so I am sort of drawing a blank on where to even start looking for the issue because there is not even an error message.
The Query I am running
export const getUserConversations = `query getUser($id: ID!) {
getUser(id: $id) {
id
conversations {
items {
conversation{
id
associated{
items{
convoLinkUserId
}
}
}
}
}
}
}
`;
Call being made in a redux actions file
export const getUserConvos = (id) => async dispatch => {
AppSyncClient.query({
query: gql(getUserConversations),
variables: {
id: id
}
}).then(res => {
console.log("RES FROM CONVO QUERY", res)
})
}
This is the response I am getting in the browser
Notice conversations.items returns an empty array.
getUser:
conversations:
items: []
__typename: "ModelConvoLinkConnection"
__proto__: Object
id: "HIDDEN_ID"
__typename: "User"
__proto__: Object
__proto__: Object
However if i run the exact same query in the playground on the AppSync console I get this...
{
"data": {
"getUser": {
"id": "HIDDEN_ID",
"conversations": {
"items": [
{
"conversation": {
"id": "HIDDEN_ID",
"associated": {
"items": [
{
"convoLinkUserId": "HIDDEN_ID"
},
{
"convoLinkUserId": "HIDDEN_ID"
}
]
}
}
},
{
"conversation": {
"id": "HIDDEN_ID",
"associated": {
"items": [
{
"convoLinkUserId": "HIDDEN_ID"
},
{
"convoLinkUserId": "HIDDEN_ID"
}
]
}
}
}
]
}
}
}
}
*HIDDEN_ID is a placeholder
I know that the objects are in my DB, however if i run the query via my react application I get nothing, and if I run it in the console on AWS I get another. I need to be able to have access to these conversations via the client. What could be causing this?

Resources