How to configure Appsync to retrieve data from a HTTP endpoint to populate a list?

1.1k Views Asked by At

I have two http endpoints setup:

GET /users/{userId}
GET /users/{userId}/notes/{noteId}

The GET User returns a payload which includes a list of multiple noteIds, which can be used to make multiple requests to the GET Note endpoint.

I am trying to configure Appsync to be able to fetch all of this data in a single query, but I can't get the list to populate with objects.

Schema:

type Query {
  getUser(userId: String!): User
  getNote(userId: String!, noteId: String!): Note
}

type User {
  userId: ID!
  firstName: String!
  lastName: String!
  notes: [Note]
}

type Note {
  noteId: ID!
  noteText: String!
  createdDatetime: Int!
}

I have a data source setup for each of the endpoints and I have a resolver for getUser and for getNote - I also have a resolver for User.notes which is the same as getNote. These resolvers have this response mapping:

#if($ctx.error)
  $util.error($ctx.error.message, $ctx.error.type)
#end
#if($ctx.result.statusCode == 200)
    $ctx.result.body
#else
    $utils.appendError($ctx.result.body, "$ctx.result.statusCode")
#end

My resolver for the GET Note (including User.note field resolver) endpoint looks like this:

{
    "version": "2018-05-29",
    "method": "GET",
    "resourcePath": $util.toJson("/prod/users/$ctx.args.userId/notes/$ctx.args.noteId"),
    "params":{
        "headers":{
            "Content-Type": "application/json",
        }
    }
}

I can see from the logs, that Appsync attempts to run the GET Note resolver, but that the resource path doesn't seem to get populated with any ids? (I can see this in the custom Authorizer on the endpoint, which logs out the method ARN which still includes the $ctx.args...

It feels like this is a common use case, but I can't find a solution, or examples anywhere. Is my approach correct, or do I need a different solution?

1

There are 1 best solutions below

1
On BEST ANSWER

I think the first problem is with your User.notes resolver and how you are accessing userId and noteId. When you have field resolvers, you should use ctx.source to access the the parent field [Ref.]. For example, you should use ctx.source.userId in your User.notes field resolver.

Secondly, as you are going to fetch individual notes from your getNote HTTP endpoint, AppSync supports this type of behavior when proxied through AWS Lambda using BatchInvoke. Please see "Advanced Use Case: Batching" on this link to get better idea. Also, I think this SO post is relevant to your use case.

One other possibility is to have another HTTP endpoint to get all the user's notes at once but I am not sure if this is possible in your case.