20

I try to include nested types defined in the following graphql schema:

type User {
  id: String!
  posts: [Post]
}

type Post {
  id: String!
}

type Query {
  getUser(id: String!): User
  getPost(id: String!): Post
}

As you can see a User has multiple Posts. I am using AppSync with an Adjacent List Dynamodb Table (which contains both the User and the Post relevant row) as a data source. Within AppSync I have to use a request mapping template, but after reading the documentation I have not understood how nested types are resolved?

I would imagine that on querying getUser the Post resolver should be called with the User_id. If so how do I access the parent id within the post resolver? Is this where ${context.source} comes into place?

As the getPost query resolver would be the same as the Post resolver, called by the getUser Post child, would I have to integrate some logic with request template of the resolver to deal with both cases?

An example would be really helpful!

DrDirk
  • 1,937
  • 3
  • 25
  • 36
  • 1
    I was struggling to find a decent answer to the same question, and finally found [this](https://medium.com/@mwarger/go-forth-and-appsync-34450c277075) Medium post, where at the end it explain very well how to retrieve data in a nested JSON object. – Cris69 Nov 08 '18 at 11:21

2 Answers2

26

You have to also write a resolver for User.posts. When you call Query.getUser it's resolver will be invoked and then if you have a resolver for User.posts it will then be invoked with the context from the first resolver set in ${context.source}.

I don't have a clean example to hand, unfortunately, but if you're using CloudFormation you'd end up with two resolvers a bit like this:

  UserResolver:
    Type: "AWS::AppSync::Resolver"
    DependsOn: Schema
    Properties:
      ApiId: !Ref YourApiId
      TypeName: Query
      FieldName: getUser
      DataSourceName: !Ref YourDataSource
      RequestMappingTemplate: # you already have this
      ResponseMappingTemplate: ...

  UserPostsResolver:
    Type: "AWS::AppSync::Resolver"
    DependsOn: Schema
    Properties:
      ApiId: !Ref YourApiId
      TypeName: User
      FieldName: posts
      DataSourceName: !Ref YourDataSource
      RequestMappingTemplate: |
        # use context.source.id here to reference the user id
      ResponseMappingTemplate: "$util.toJson($ctx.result.items)"

That is pretty much it. You were on the right track but the mapping from fields to resolvers needs to be more explicit than you were thinking.

macbutch
  • 3,241
  • 2
  • 27
  • 27
  • 2
    Thanks for this. It was not possible for me to find this in the documentation (I missed it I think because there were no nested examples like this), other than a vague reference to the context object containing the results of the parent. I now realized I had incorrectly assumed the resolvers were specified only within the Query or Mutation types and ignore that they could be specified anywhere, which is standard graphQL. Thanks again! – Francis Upton IV Jul 17 '18 at 14:33
  • 3
    Glad it helped, @FrancisUpton. I've found the docs a little difficult to navigate too and it took us a while to figure out how to do this too. – macbutch Jul 18 '18 at 05:20
  • @macbutch I didn't know that. Can I use that with Amplify and editing manually the JSON templates? (Note I am not using DynamoDB, but RDS). Thanks a lot. – Ricardo Jan 06 '21 at 18:10
  • What about if posts is paginated? Thanks – Ricardo Jan 08 '21 at 11:31
  • 1
    @Ricardo probably too late to help but we're not using Amplify so I don't know for sure but I don't see that it would be a problem. Pagination details will vary to some degree based on your backend but I'd recommend the [graphql docs on pagination](https://graphql.org/learn/pagination/). We use a Connection type with Dynamo and the basic approach should work for you too (though I'd expect it to look a little different). – macbutch Feb 03 '21 at 06:09
  • Thank you for this post. I tried to figure out how to handle nested objects for hours... – TorbenVerdorben May 21 '21 at 09:07
3

Here is another stackoverflow post where, I describe how to do this in detail. The title says mutation but it goes over both mutations and queries. mutation to create relations on AWS AppSync

mparis
  • 3,623
  • 1
  • 17
  • 16