Current implementation doesn't offer customers a smooth ability to create AppSync Functions for Pipeline Resolvers.
Supersedes #6923
If users want to utilize AppSync's graphQL functions that are serializable and functionable.
Workaround currently would be to make Lambda Functions but these are expensive and will costly for customers.
Possible solution could be to create an class that creates AppSync Functions
interface GraphQLFunctionProps {
dataSourceName: string,
description: string,
functionVersion: string,
name: string,
requestMappingTemplate?: MappingTemplate,
responseMappingTemplate?: MappingTemplate,
}
class GraphQLFunction extends Construct { ... }
class GraphQLApi extends Construct {
...
createGraphQLFunction(...);
...
}
The Function that can be added to the pipelineConfig is not a Lambda Function. Instead, it is AppSync::Function.
See documentation on pipelineConfig here.
See documentation on functionConfiguration here.
See documentation on appsync:CreateFunction here.
This is a :rocket: Feature Request
I think this feature is not yet in CDK.
Is there a work around to create pipeline resolvers with appsync functions in CDK?
It isn't a feature yet, but will be in the works soon!
You can use the L1 constructs, specifically appsync.CfnFunctionConfiguration.
CfnFunctionConfigurationProps
/**
* Properties for defining a `AWS::AppSync::FunctionConfiguration`
*
* @stability external
* @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appsync-functionconfiguration.html
*/
export interface CfnFunctionConfigurationProps {
/**
* `AWS::AppSync::FunctionConfiguration.ApiId`
* @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appsync-functionconfiguration.html#cfn-appsync-functionconfiguration-apiid
*/
readonly apiId: string;
/**
* `AWS::AppSync::FunctionConfiguration.DataSourceName`
* @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appsync-functionconfiguration.html#cfn-appsync-functionconfiguration-datasourcename
*/
readonly dataSourceName: string;
/**
* `AWS::AppSync::FunctionConfiguration.FunctionVersion`
* @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appsync-functionconfiguration.html#cfn-appsync-functionconfiguration-functionversion
*/
readonly functionVersion: string;
/**
* `AWS::AppSync::FunctionConfiguration.Name`
* @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appsync-functionconfiguration.html#cfn-appsync-functionconfiguration-name
*/
readonly name: string;
/**
* `AWS::AppSync::FunctionConfiguration.Description`
* @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appsync-functionconfiguration.html#cfn-appsync-functionconfiguration-description
*/
readonly description?: string;
/**
* `AWS::AppSync::FunctionConfiguration.RequestMappingTemplate`
* @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appsync-functionconfiguration.html#cfn-appsync-functionconfiguration-requestmappingtemplate
*/
readonly requestMappingTemplate?: string;
/**
* `AWS::AppSync::FunctionConfiguration.RequestMappingTemplateS3Location`
* @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appsync-functionconfiguration.html#cfn-appsync-functionconfiguration-requestmappingtemplates3location
*/
readonly requestMappingTemplateS3Location?: string;
/**
* `AWS::AppSync::FunctionConfiguration.ResponseMappingTemplate`
* @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appsync-functionconfiguration.html#cfn-appsync-functionconfiguration-responsemappingtemplate
*/
readonly responseMappingTemplate?: string;
/**
* `AWS::AppSync::FunctionConfiguration.ResponseMappingTemplateS3Location`
* @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appsync-functionconfiguration.html#cfn-appsync-functionconfiguration-responsemappingtemplates3location
*/
readonly responseMappingTemplateS3Location?: string;
}
So to create your appsync function it would look something like this:
Creating an AppSync Function
const appsyncFunction = new appsync.CfnFunctionConfiguration(stack, 'function', {
apiId: api.apiId,
dataSourcename: dataSource.name,
functionVersion: '1.0.0',
name: 'myFunction',
requestMappingTemplate: appsync.MappingTemplate.fromFile('filepath').renderTemplate(),
responseMappingTemplate: appsync.MappingTemplate.fromFile('filepath').renderTemplate(),
});
And adding it to a resolver would look like the following:
Creating a Pipeline Resolver
const pipelineResolver = new appsync.Resolver(stack, 'resolver', {
api: api,
typeName: 'Query',
fieldName: 'fieldName',
pipelineConfig: [appsyncFunction.name],
});
Thanks Bryan.
I am able to create pipeline resolver with CfnFunctionConfiguration and CfnResolver.
Regards
Prakhar
@BryanPan342
Hi, one of the things I ran into is that when using new GraphqlApi(this, 'AnApi', {}) is that when you add resolvers like pipeline, you can use CfnFunctionConfiguration for registering your pipeline function.
For the requestMappingTemplate it expects a string.
Then when you want to attach resolvers to your API,
you can either:
1) attach resolvers to datasources
2) attach resolvers to API and provide a Datasource.
When using :
new Resolver(this, resolverName, {
api: this.api,
...
typescript is complaining if I don't make my api of the IGraphqlApi instead of GraphqlApi which is what the GraphqlApi constructor returns. Luckily using the other type is not an issue but for consistency it would be better to have the Resolver accept api type GraphqlApi?
Also the requestMappingTemplate for Resolver is of type MappingTemplate and not string, which is fine and when the CfnFunctionConfiguration will be replaced by a higher level class I think it would also expect a MappingTemplate, am I right?
Finally, what is best practice: Adding resolvers to API and supply a Datasource, or add Resolvers to the Datasources which are linked to the API?
All in all I do like the compressed code. I have been removing a lot of unnecessary jumble and my CDK code is becoming much cleaner and easy to read.
The only thing maybe is that it is sometimes unclear if all Roles and necessary Policies are created to execute Lambdas via resolvers etc. But for now it is trial and error.
@mattiLeBlanc i wrote up a PR for pipeline functions #10111
Luckily using the other type is not an issue but for consistency it would be better to have the Resolver accept api type GraphqlApi?
Our design guidelines make it such that using the IGraphqlApi should be the reference because that way you can have multiple stacks. To be honest, I'm suprised to hear that the typescript is complaining.. maybe we need an explicit implements IGraphqlApi at the end of the class declaration..
Adding resolvers to API and supply a Datasource, or add Resolvers to the Datasources which are linked to the API?
Depends on what kind of resolver you want. In the #10111 PR, we make it so that all resolvers are under the API scope instead of the data source scope (which is more consistent with the architecture of AppSync). But generally I would say if you are making a unit resolver with a data source, it is easier to do dataSouce.createResolver(...). And in the upcoming PR, you will be able to do api.createResolver(...) for convenience and to create pipeline resolvers easily!
The only thing maybe is that it is sometimes unclear if all Roles and necessary Policies are created to execute Lambdas via resolvers etc. But for now it is trial and error.
look into the Permissions section of the readme for roles and policies!
Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.