3

I'm trying to get a record from a GSI and I'm stucked.

API Schema:

type DriverInfos {
    id: String!
    status: Int
    lastLat: Float
    lastLng: Float
    idDriver: String # GSI
}

type Query {
    getDriverInfosByDriver(idDriver: String): DriverInfos
}

Resolver :

{
    "version" : "2017-02-28",
    "operation" : "Query",
    "index" : "idDriver-index",
    "query" : {
        ## Provide a query expression. **
        "expression": "#idDriver = :idDriver",
        "expressionNames" : {
            "#idDriver" : "idDriver"
        },
        "expressionValues" : {
            ":idDriver" : {
                "S" : "${ctx.args.idDriver}"        
            }
        }
    }
}

Query :

query getDriverInfosByDriver{
  getDriverInfosByDriver(idDriver: "1") 
    {    
      idDriver
      status
      lastLat
      lastLng 
    }
}

Return :

{
  "data": {
    "getDriverInfosByDriver": {
      "idDriver": null,
      "status": null,
      "lastLat": null,
      "lastLng": null
    }
  }
}

GSI is well activated : Name : "idDriver-index" - PartitionKey : idDriver (String) Try with other ids : 2, 3, ...

It seems that it comes from the resolver. I tried with different resolver but it always return an error.

Thank you in advance for your answers.

Jobel
  • 236
  • 1
  • 3
  • 13

1 Answers1

11

The issue is that a Query operation always returns a set of results not just one. If you want to leave your query type like this:

type Query {
    getDriverInfosByDriver(idDriver: String): DriverInfos
}

then you should to change your response mapping template to this:

#if($ctx.result.items.size() > 0)
  $util.toJson($ctx.result.items[0])
#else
  null
#end

If instead the getDriverInfosByDriver query should return multiple info objects then you should change your schema to:

type DriverInfo {
    id: String!
    status: Int
    lastLat: Float
    lastLng: Float
    idDriver: String # GSI
}

type DriverInfoConnection {
  items: [DriverInfo]
  nextToken:String
}

type Query {
    getDriverInfosByDriver(idDriver: String): DriverInfoConnection
}

You can then leave your response mapping template as the default:

$util.toJson($ctx.result)

and then query it like so

query getDriverInfosByDriver{
  getDriverInfosByDriver(idDriver: "1") {
    items {    
      idDriver
      status
      lastLat
      lastLng 
    }
  }
}
mparis
  • 3,623
  • 1
  • 17
  • 16
  • Great thanks ! Well explicated and really helpful ! I wanted to return only one item so I change the response mapping template to return the first item... – Jobel Aug 30 '18 at 07:51
  • I just saw your AWS webinar on YT and would love you to take a look at my question: https://stackoverflow.com/questions/54269487/appsync-query-resolver-are-expressionnames-and-expressionvalues-necessary – lurning too koad Jan 19 '19 at 17:19
  • I guess I'm confused on how the initial one setup by AWS works then using id as it uses the $util.toJson($ctx.result). I've attempted to replicate it using username and adding in the index but it always returns null. – MattE Jul 02 '19 at 13:17