DrDirk
DrDirk

Reputation: 1997

AppSync: Nested Type Resolver

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!

Upvotes: 20

Views: 12296

Answers (2)

mparis
mparis

Reputation: 3683

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

Upvotes: 3

macbutch
macbutch

Reputation: 3291

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.

Upvotes: 26

Related Questions