* Which Category is your question related to? *
GraphQL API
* What AWS Services are you utilizing? *
AppSync, DynamoDB, Cognito
* Provide additional details e.g. code snippets *
We're creating a GraphQL API using amplify add api. The vast majority of the API can use the autogenerated code backed by DynamoDB. However, there is one model Person for which we want to fetch data from the Cognito user pool.
I was planning to use custom resolvers using Lambda functions for this purpose, but can't figure out how to handle connections.
In simplified terms, we would have the following schema.graphql:
type Person @model(queries: null, mutations: null, subscriptions: null) {
id: ID!
firstName: String
lastName: String
}
type Post @model {
id: ID!
title: String!
author: Person @connection
}
To be precise, the Person type should not be annotated with @model directive, as the model is not stored in DynamoDB, but the @connection does not work without it.
I can prevent the generation of default getPerson etc. queries and implement them using custom resolvers. However, I also need to override the default Post.author resolver.
I could add a custom resolver template in resolvers/Post.author.req.vtl, but the data source would still be defined to be a DynamoDB table (instead of a Lambda function) in the autogenerated CF stack.
Is there any way to override the autogenerated CF resolver definition / data source in addition to overriding the resolver vtl templates?
We have examples of Custom resolver lambda in the docs. Let me know if you need any additional help
I've gone through the docs and know how to create a custom query resolver. What I haven't been able to do is to create a custom resolver that is used by other types through @connection.
In the example I provided, I know how to create a custom resolver for getPerson. What I haven't been able to figure out is how to make Post.author use a Lambda function. While I can override the Post.author.req.vtl resolver template, I cannot override the autogenerated CloudFormation stack template which defines the data source as DynamoDB instead of Lambda.
These docs describe how to connect a lambda resolver (https://aws-amplify.github.io/docs/cli/graphql#add-a-custom-resolver-that-targets-an-aws-lambda-function). To do this you should remove the @model from Person, remove @connection from Post.author, follow the instructions here to add a lambda resolver on the Post.author field (e.g. in the CFN doc the "TypeName": "Post" and "FieldName": "author".
PR #1346 implements the @function directive that provides a much simpler interface for configuring lambda resolvers (although the process is very similar under the hood). Once this is merged, you will be able to do:
type Person {
id: ID!
firstName: String
lastName: String
}
type Post @model {
id: ID!
title: String!
author: Person @function(name: "ResolveUserPoolUser")
}
I'd also point you to #1060 which discusses supporting custom transformers. With this you would be able to implement your own @resolveUser directive that configures a call to AWS Cognito User Pools and can be used in multiple places throughout the schema.
I have added this as an example in the Amplify docs. As soon as these PRs from the docs (https://github.com/aws-amplify/docs/pull/640) and cli (https://github.com/aws-amplify/amplify-cli/pull/1346) are merged you will be able to add this without much trouble.
@mikeparisstuff the @function appears to be working nicely now it's merged in
These docs describe how to connect a lambda resolver (https://aws-amplify.github.io/docs/cli/graphql#add-a-custom-resolver-that-targets-an-aws-lambda-function). To do this you should remove the @model from Person, remove @connection from Post.author, follow the instructions here to add a lambda resolver on the Post.author field (e.g. in the CFN doc the "TypeName": "Post" and "FieldName": "author".
PR #1346 implements the
@functiondirective that provides a much simpler interface for configuring lambda resolvers (although the process is very similar under the hood). Once this is merged, you will be able to do:type Person { id: ID! firstName: String lastName: String } type Post @model { id: ID! title: String! author: Person @function(name: "ResolveUserPoolUser") }I'd also point you to #1060 which discusses supporting custom transformers. With this you would be able to implement your own
@resolveUserdirective that configures a call to AWS Cognito User Pools and can be used in multiple places throughout the schema.
Hi,
Im looking for similar solution, but i want to know what arguments will Lambda function receive to identify the user, like user ID, my model will have multiple users, and i want all off them to be resolved by a common function.
for example
type Person {
id: ID!
firstName: String
lastName: String
}
type Post @model {
id: ID!
title: String!
author: Person @function(name: "ResolveUserPoolUser")
editor: Person @function(name: "ResolveUserPoolUser")
}
In case anyone is looking for an answer to @madhurvyas1 question:
the function event.typeName will be "Post" for both function calls, but the event.fieldName will be "author" for one and "editor" for second, so you can distinguish which one of them is being resolved.
I have also the same issue, why does he can't use a custom resolver with the connections. why does he need to use function directive? and what about the typing when you have 6 levels of dep ? which is auto-generated how you make all this connection work.
I have issues connecting all of that stuff. ( I'll be really happy to work with an expert on that), and pay of course i really need help! Thanks.