Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[aws-appsync]: implementation for appsync::functionConfiguration for Pipeline Resolvers #9092

Closed
BryanPan342 opened this issue Jul 16, 2020 · 6 comments · Fixed by #10111
Closed
Assignees
Labels
@aws-cdk/aws-appsync Related to AWS AppSync effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. in-progress This issue is being actively worked on. p1

Comments

@BryanPan342
Copy link
Contributor

Current implementation doesn't offer customers a smooth ability to create AppSync Functions for Pipeline Resolvers.

Supersedes #6923

Use Case

If users want to utilize AppSync's graphQL functions that are serializable and functionable.

Proposed Solution

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(...);
...
}

Other

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 🚀 Feature Request

@BryanPan342 BryanPan342 added feature-request A feature should be added or improved. needs-triage This issue or PR still needs to be triaged. labels Jul 16, 2020
@BryanPan342 BryanPan342 self-assigned this Jul 16, 2020
@github-actions github-actions bot added the @aws-cdk/aws-appsync Related to AWS AppSync label Jul 16, 2020
@BryanPan342 BryanPan342 added p1 effort/medium Medium work item – several days of effort and removed needs-triage This issue or PR still needs to be triaged. labels Jul 16, 2020
@prax0724
Copy link

I think this feature is not yet in CDK.
Is there a work around to create pipeline resolvers with appsync functions in CDK?

@BryanPan342
Copy link
Contributor Author

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],
});

@prax0724
Copy link

Thanks Bryan.

I am able to create pipeline resolver with CfnFunctionConfiguration and CfnResolver.

Regards
Prakhar

@BryanPan342 BryanPan342 added the in-progress This issue is being actively worked on. label Sep 2, 2020
@mattiLeBlanc
Copy link

mattiLeBlanc commented Sep 11, 2020

@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.

@BryanPan342
Copy link
Contributor Author

@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!

@mergify mergify bot closed this as completed in #10111 Dec 7, 2020
mergify bot pushed a commit that referenced this issue Dec 7, 2020
Support AppSync Function by exposing Function Configuration. 

**BREAKING CHANGES**: `Resolver.pipelineConfig` no longer supports `string[]`
- **AppSync**: `Resolver.pipelineConfig` no longer supports `string[]`, instead use `AppsyncFunction`
- **AppSync**: Resolvers are scoped from `GraphqlApi` instead of its `Data Source`, this means that the **logical id** of resolvers will change!

Fixes #9092

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@github-actions
Copy link

github-actions bot commented Dec 7, 2020

⚠️COMMENT VISIBILITY WARNING⚠️

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.

skiyani pushed a commit to skiyani/aws-cdk that referenced this issue Dec 7, 2020
Support AppSync Function by exposing Function Configuration. 

**BREAKING CHANGES**: `Resolver.pipelineConfig` no longer supports `string[]`
- **AppSync**: `Resolver.pipelineConfig` no longer supports `string[]`, instead use `AppsyncFunction`
- **AppSync**: Resolvers are scoped from `GraphqlApi` instead of its `Data Source`, this means that the **logical id** of resolvers will change!

Fixes aws#9092

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
flochaz pushed a commit to flochaz/aws-cdk that referenced this issue Jan 5, 2021
Support AppSync Function by exposing Function Configuration. 

**BREAKING CHANGES**: `Resolver.pipelineConfig` no longer supports `string[]`
- **AppSync**: `Resolver.pipelineConfig` no longer supports `string[]`, instead use `AppsyncFunction`
- **AppSync**: Resolvers are scoped from `GraphqlApi` instead of its `Data Source`, this means that the **logical id** of resolvers will change!

Fixes aws#9092

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-appsync Related to AWS AppSync effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. in-progress This issue is being actively worked on. p1
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants