Search code examples
graphqlaws-appsync

Accessing json array in AWS AppSync


I am new to AWS AppSync and am trying to use an HTTP endpoint to fetch data from an external API. Here is an example of what that API returns.

{
  "status": 1,
  "size": 3,
  "result": [
    {
      "number": "123",
      "program": "program name",
      "team_name": "team name",
      "robot_name": "robot name",
      "organisation": "team organization",
      "city": "team city",
      "region": "team state",
      "country": "team country",
      "grade": "team grade",
      "is_registered": 0
    },
    {
      "number": "456",
      "program": "program name",
      "team_name": "team name",
      "robot_name": "robot name",
      "organisation": "team organization",
      "city": "team city",
      "region": "team state",
      "country": "team country",
      "grade": "team grade",
      "is_registered": 0
    },
    {
      "number": "789",
      "program": "program name",
      "team_name": "team name",
      "robot_name": "robot name",
      "organisation": "team organization",
      "city": "team city",
      "region": "team state",
      "country": "team country",
      "grade": "team grade",
      "is_registered": 0
    }
  ]
}

Here is my GraphQL Schema

type Query {
    getTeams(number: String!): Team
}

type Team {
    number: String
    program: String
    teamName: String
    robotName: String
    organization: String
    city: String
    region: String
    country: String
    grade: String
    isRegistered: Int
}

schema {
    query: Query
}

Here is my request mapping template

{
    "version": "2018-05-29",
    "method": "GET",
    "resourcePath": "/v1/get_teams",
    "params":{
        "query": {
            "APIKEY": "API_KEY_GOES_HERE"
        },
        "headers": {
            "Content-Type": "application/json"
        }
    }
}

And here is my response mapping template

#if($context.result.statusCode == 200)
## Success - decode the body and reconstruct the response with the schema in mind
#set($response = $util.parseJson($context.result.body))

#set($result = {
 "number": $response.result[0].number,
 "program": $response.result[0].program,
 "teamName": $response.result[0].team_name,
 "robotName": $response.result[0].robot_name,
 "organization": $response.result[0].organisation,
 "city": $response.result[0].city,
 "region": $response.result[0].region,
 "country": $response.result[0].country,
 "grade": $response.result[0].grade,
 "isRegistered": $response.result[0].is_registered
})
$util.toJson($result)
#else
## Error - send the proper error message
$utils.appendError($ctx.result.body, $ctx.result.statusCode)
#end

What I have currently worked but only returns one team. My question is how can I get the GraphQL query to return an array of teams by getting all of the items from the result array in the JSON file?


Solution

  • I'm not sure if I really understood what you are trying to achieve but here it goes:

    If you want to return an array of teams instead of a single team, you have to modify your query in the schema as follow:

    type Query {
        getTeams: [Team]
    }
    

    Now on the response mapping you can map directly the response to your array:

    #if($ctx.result.statusCode == 200)
        ## If response is 200, return the body.
        $util.toJson($util.parseJson($ctx.result.body).result)
    #else
        ## If response is not 200, append the response to error block.
        $utils.appendError($ctx.result.body, "$ctx.result.statusCode")
    #end
    

    At this point I noticed that you renamed the fields in your schema so it does not match anymore; for example your json is returning team_name but your graphQL schema is expecting teamName.

    What I would do is to modify the schema to match with the JSON as follow:

    type Team {
        number: String
        program: String
        team_name: String
        robot_name: String
        organisation: String
        city: String
        region: String
        country: String
        grade: String
        is_registered: Int
    }
    

    And then use alias in the query to return the fields with the expected name, for example:

    query{
      getTeams{
        number: number
        teamName:team_name
        robotName: robot_name
        organization: organisation
      }
    }
    

    That will produce the output that I think that you are expecting:

    {
      "data": {
        "getTeams": [
          {
            "number": "123",
            "teamName": "team name",
            "robotName": "robot name",
            "organization": "team organization"
          },
          ....