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!
Resolvers provide the implementation for how AppSync processes queries and mutations. They connect the GraphQL schema, the abstract definition of the API, and the services that provide the data, such as a database or a Lambda function. In practice, most of AppSync development is spent writing resolvers.
From the pipeline resolver page, on the Functions section, click on Create Function. It is also possible to create functions without going through the resolver page, to do this, in the AWS AppSync console, go to the Functions page. Choose the Create Function button.
VTL is a logical template language that gives you the power to manipulate both the request and the response in the standard request/response flow of a web application, using techniques such as: Default values for new items. Input validation and formatting. Transforming and shaping data.
AWS AppSync provides a robust, scalable GraphQL interface for application developers to combine data from multiple sources, including Amazon DynamoDB, AWS Lambda, and HTTP APIs.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With