AppSync: Nested Type Resolver
Asked Answered
D

2

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!

Dreeda answered 14/7, 2018 at 18:59 Comment(1)
I was struggling to find a decent answer to the same question, and finally found this Medium post, where at the end it explain very well how to retrieve data in a nested JSON object.Deerhound
A
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.

Agriculturist answered 16/7, 2018 at 23:59 Comment(6)
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!Elsworth
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.Agriculturist
@Agriculturist 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.Edva
What about if posts is paginated? ThanksEdva
@Edva 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. 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).Agriculturist
Thank you for this post. I tried to figure out how to handle nested objects for hours...Spermatophyte
T
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

Twilatwilight answered 17/7, 2018 at 17:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.