Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send JSON array through graphQL and AWS AppSync to add data to Dynamo Table?

What I'm trying to do is to send data from a React Native app through AppSync so that I can update a user's data on a dynamo table. I can perform all of my CRUD operations, just not a list of data. When I try, I get an error that what I'm sending isn't a valid JSON. However, my input passes as valid JSON when I put it through a JSON linter.

To try and solve this problem, I've changed my input flow to the simplest possible process. Originally I was pulling my JSON from a parsed JSON string that was locally cached. I thought that perhaps there was an issue with the JSON.parse(obj) function. That didn't hold up to reason. So I moved all of my input out of a JS object and into a JSON that isn't stored in a variable beforehand but is directly passed to the API I'm using (https://aws-amplify.github.io/docs/js/api).

After this didn't work, I thought that maybe my GraphQL Schema was wrong for the object type I was sending, but didn't find anything amiss.

My schema in AppSync using GraphQL is defined as follow:

input CreateUserInput {
  email: String!
  data: AWSJSON
}

The request I'm sending is as follows:

const dbReturn = await API.graphql(graphqlOperation(
  mutations.createUser, {
    input: {
      "email": "[email protected]",
      "data": [{
        "num": 34,
      }]
    }
  }
));

The error message says:

"Variable 'data' has an invalid value. Unable to parse [{num=34}] as valid JSON."

What confuses me is that "[{num=34}]" isn't the input I'm giving it. I'm sending it "[{"num": 34}]" which is valid JSON. I would expect it to be able to parse my input and send the data to my dynamo table seeing as the JSON input is valid.

Anybody have any ideas what I can do to get past this? Thank you for the help!

like image 523
ianarko Avatar asked Dec 11 '22 02:12

ianarko


2 Answers

Figured it out. The answer lies in the GraphQL schema.

"createUser": {
    "email": "Hello, world!",
    "data": "{\"key\":\"value\"}",
}

The input for a "complex data type" is just a string. So when making the request, you just have to pass in the data as something something like JSON.stringify(variable.data). I hope this helps someone along the way.

like image 93
ianarko Avatar answered Jan 22 '23 22:01

ianarko


I had the opposite issue. I am not using code to create the query but using gql directly. If I use String in input then I get a stringified JSON in my db which is not what I want. Instead I had to ensure there were no quotes around - in your case, num.

Schema

Item {
 data: AWSJSON
}
ItemInput {
  data: AWSJSON
}

Query

mutation {
 createUser {
   data: { num: 34 } // Not { "num": 34 }
 }
}

This ensures my data is not stored as a string and that on query I get parseable JSON back instead of a quote escaped string.

My VTL templates do do anything unusual on mutations but on query I do return as:

{
  "data" :  $util.toJson($ctx.result.get('data')) // OR $ctx.result.get('data').toJSON()
}
like image 45
cyberwombat Avatar answered Jan 23 '23 00:01

cyberwombat