Is there support for custom resolvers that are not overwritten by amplify api gql-compile
? I could not find any documentation on this.
For example, consider a lambda function as a source for a GraphQL type. The GraphQL type would require a custom resolver and also the correct references in the cloudformation template.
From the transform perspective, the way to write custom logic is to write a transformer. You can read more about this here https://github.com/aws-amplify/amplify-cli/blob/master/how-to-write-a-transformer.md. In response to the lambda use case, a @function
directive will be supported soon and will allow you to easily call out to lambda from within the schema.graphql.
From the CLI perspective, it would be possible to allow you to write resolvers with .vtl files that you place in the backend directory and are automatically deployed for you but this would take a little bit of work.
amplify api add/update/delete resolver
flow.gql-compile
.I think we should tag this as a feature request and think about the best approach.
We also need http resolvers...
Is there an approach we can take to link in a manually managed SAM file while we wait for features like this to come out? I'm struggling to see how to get started with amplify-cli. We need http and lambda resolvers. And we need to point CodePipeline at our some CF file so we can easily maintain dev, test, and production environments.
+1 to http resolvers. We have talked about various approaches and this warrants an issue to discuss more. This again will be a new directive in the transform.
As for what you can do now, we do export some values from the cloudformation templates. You could then use CloudFormation ImportValue functions to pull those exported values (such as the GraphQL API Id) and then put your own resolvers and data sources in your own template. Put all your schema parts in the schema.graphql and just reference the type/field in your own template. If you need any other values exported let me know.
Thanks Mike! I will follow those feature requests.
Custom resolvers in a separate CloudFormation template that pulls required values from the generated CloudFormation template make the most sense to me. Keeping and referencing the schema parts in the schema.graphql as you said.
What I did to solve my imminent need was to use the CLI to create 95% of my API and just added the custom resolvers in the App Sync UI for my special parts.
@emilbryggare @afterthought one way we are thinking of doing this is to allow you to specify resolver templates in a directory with a syntax of Type.Field.request and Type.Field.Response where the Type and the Field correspond to your GraphQL schema. For instance you might have Query.listPosts.request or Mutation.addPost.response for the following:
type Query {
listPosts(limit: Int, nextToken: String): [Posts]
}
type Mutation {
addPost(name:String! description: String): Post
}
The CLI would then be knowledgeable enough to merge this with the transformation flow, or just use them independently in an add/update flow, and apply them to your API.
Would something like this work for you? The other benefit of this is it would allow you to perform local testing and mocking in the future of your own custom resolver templates as long as you saved the files in this naming convention.
@undefobj that would definitely solve the needs of our custom resolvers.
However, it just struck me that we probably will need custom sources as well. For example data in a shared DynamoDB. Maybe a similar approach for that or something like this?
// In this example, Amplify will create and provision the DB
type Store @model {
name: String!
settings: [String!]
}
// In this example, Amplify should create access policies to arn:aws:db1 and define it as a source
type Store @source arn:aws:db1 {
name: String!
Settings: [String!]
}
@emilbryggare that wouldn't be a direction we would want to go here. The point of the annotations and GraphQL transformer is to abstract implementation away, and the above is leaking it into the abstraction. The capabilities to specify data sources already exist in CloudFormation and the CLI lets you create resources independently and use them in creation of your API. What we could do is make it easier to create a DynamoDB table (or other data source) through the appropriate CLI category and then use it with your custom resolver templates as above, but this would be independent of the transformer syntax and functionality.
@undefobj ok - that makes sense. I'm happy with the proposed solution for custom resolvers, that would help a lot.
Just adding a use case to this as it would be super useful to push your own custom resolvers.
For the application we are writing we have to allow a user only to add to an list of objects in DynamoDB for the profile. This is easily done by writing a custom resolver for AWS AppSync that looks similar to this: #set( $expression = "$expression $entry.key = list_append($entry.key, $entry.value)" )
. This currently can't be done using Amplify and every time you update your models you have to go and change the resolver again in the console.
@undefobj @mikeparisstuff i've implemented something akin to this in another repo.
Putting the resolvers with that naming in custom/resolvers/
folder
However, the idea was to add to what's already there, so there is no creation of new data sources. it pretty much expects the data sources to already be there (e.g.: from @model)
@kaustavghosh06 can you please track as much of this is part of the API category flow for the CLI and independent of the transformer.
@emilbryggare that wouldn't be a direction we would want to go here. The point of the annotations and GraphQL transformer is to abstract implementation away, and the above is leaking it into the abstraction. The capabilities to specify data sources already exist in CloudFormation and the CLI lets you create resources independently and use them in creation of your API. What we could do is make it easier to create a DynamoDB table (or other data source) through the appropriate CLI category and then use it with your custom resolver templates as above, but this would be independent of the transformer syntax and functionality.
I'm afraid this approach will leave users who use amplify-cli in multiple related projects without a way to reference their data sources or DynamoDB tables across projects.
I wonder if api
should get an amplify api datasource add/update/delete
flow. Hopefully, one that allows in and out of project resources as data sources.
The method @undefobj proposes for custom resolvers in a predictable named format works well, I can +1 that. Its similar to what I'm doing now (and I believe Serverless does the same). I basically use the CF template as a project file for my source code, and my deployment steps are an s3 sync command to move the template and all of the resolver VLT files up to a bucket before loading it into a CF change set.
Hi, just wondering if there's any update on this?
The way we see we could go about it now is by using a custom cloudformation template with AWS::AppSync::DataSource and AWS::AppSync::Resolver
We noticed amplify add function
with 3 templates (hello world, and two API Gateway related) , it would be great to have a Lambda Resolver template to be added in there as well (which would generate a DataSource, simple resolver mapping template and permissions for AWS AppSync to call that function)
Adding a custom cloudformation template with Lambdas, DataSources and Resolvers and running aws cloudformation deploy
worked at first, as @mikeparisstuff suggested, but one of the amplify push
commands have overwritten these resolvers but subsequent cloudformation deploy
would not recreate them
@mkrn We introduced a new flag with CLI version 0.1.29 for the amplify push command -‘amplify push —no-gql-override’ which wouldn’t override your resolvers on a push.
@kaustavghosh06 Yay! Thanks will give it a try.
@undefobj @mikeparisstuff i've implemented something akin to this in another repo.
Putting the resolvers with that naming incustom/resolvers/
folder
However, the idea was to add to what's already there, so there is no creation of new data sources. it pretty much expects the data sources to already be there (e.g.: from @model)
@onlybakam, can you please elaborate a little bit more on your implementation? What exactly you put in custom/resolvers/
?
@mkrn - Are you able to provide an example repo showing how you approached linking the CF resources (Lambda Resolvers, and DynamoDB) with the Amplify resources (Schema)? What is the workflow?
@CiscoKidxx Here is a repository that shows how to use the custom resources/resolvers features of the updated CLI: https://github.com/mikeparisstuff/amplify-cli-nested-api-sample. As the readme mentions, this uses a build of the CLI that is not yet merged into master but that is available to test on github. You can see from this repo and example of how to add a custom resolver that targets a table created by @model, add a custom resolver that targets the Elasticsearch Cluster created by @searchable, and add a custom resolver that targets a AWS Lambda function created by amplify add function
.
Thanks @mikeparisstuff! Very cool! Does this version support multienv?
Yes, it is forked off the multienv branch.
@mikeparisstuff That is really great content! Can it be added to the future documentation?
@mikeparisstuff. Outstanding! Very helpful info.
Hey guys,
We've added functionality for custom resolvers in the main version of the CLI. Please use npm install -g @aws-amplify/cli
to install the latest version of the CLI. For documentation regarding it, please refer to https://aws-amplify.github.io/docs/cli/graphql#overwrite-a-resolver-generated-by-the-graphql-transform
Here's the launch announcement for the same - https://aws.amazon.com/blogs/mobile/amplify-adds-support-for-multiple-environments-custom-resolvers-larger-data-models-and-iam-roles-including-mfa/
@kaustavghosh06 The link is dead. https://aws-amplify.github.io/docs/cli/graphql#overwrite-a-resolver-generated-by-the-graphql-transform Takes to the main doc.
@babus The custom resolvers section is on that page itself. Use https://aws-amplify.github.io/docs/cli-toolchain/graphql#custom-resolvers for quick navigation.
Most helpful comment
Hey guys,
We've added functionality for custom resolvers in the main version of the CLI. Please use
npm install -g @aws-amplify/cli
to install the latest version of the CLI. For documentation regarding it, please refer to https://aws-amplify.github.io/docs/cli/graphql#overwrite-a-resolver-generated-by-the-graphql-transformHere's the launch announcement for the same - https://aws.amazon.com/blogs/mobile/amplify-adds-support-for-multiple-environments-custom-resolvers-larger-data-models-and-iam-roles-including-mfa/