aws-amplify / amplify-cli

The AWS Amplify CLI is a toolchain for simplifying serverless web and mobile development.
Apache License 2.0
2.81k stars 821 forks source link

Firing subscription events from custom resolvers with @function #2520

Closed rawadrifai closed 5 years ago

rawadrifai commented 5 years ago

Which Category is your question related to? Subscriptions

What AWS Services are you utilizing? Dynamo, AppSync, Cognito, Lambda

Provide additional details e.g. code snippets I am using a lambda custom resolver to insert multiple items in dynamo db, so I don't have to make multiple queries(mutations) from the client. I use the dynamodb sdk to insert the data. I assume subscribers are not supposed to receive onCreate notifications if I do it like this. How can I get the lambda to fire the onCreate events? Should I be using API from aws-amplify in my lambda to insert data instead of dynamo sdk? That would require I authenticate again from the lambda, I assume. Can I reclaim the caller's credentials somehow instead of creating a separate Cognito user for the lambda?

ambientlight commented 5 years ago

@rawadrifai: what you can do is use local resolvers with None datasource for a custom mutation that you can define via your custom resolvers. To this mutation you can attach the subscription with @aws_subscribe. You would need to an execution policy to lambda that allows appsync:GraphQL on your api category graphql resource.

Example can be: /stacks/CustomResolvers.json

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "An auto-generated nested stack.",
    "Metadata": {},
    "Parameters": {
        "AppSyncApiId": {
            "Type": "String",
            "Description": "The id of the AppSync API associated with this project."
        },
        "AppSyncApiName": {
            "Type": "String",
            "Description": "The name of the AppSync API",
            "Default": "AppSyncSimpleTransform"
        },
        "env": {
            "Type": "String",
            "Description": "The environment name. e.g. Dev, Test, or Production",
            "Default": "NONE"
        },
        "S3DeploymentBucket": {
            "Type": "String",
            "Description": "The S3 bucket containing all deployment assets for the project."
        },
        "S3DeploymentRootKey": {
            "Type": "String",
            "Description": "An S3 key relative to the S3DeploymentBucket that points to the root\nof the deployment directory."
        }
    },
    "Resources": {
        "SomethingUpdatedDataSource": {
            "Type": "AWS::AppSync::DataSource",
            "Properties": {
                "ApiId": {
                    "Ref": "AppSyncApiId"
                },
                "Name": "SomethingUpdatedDataSource",
                "Type": "NONE"
            }
        },
        "SomethingUpdatedResolver": {
            "Type": "AWS::AppSync::Resolver",
            "DependsOn": [
                "SomethingUpdatedDataSource"
            ],
            "Properties": {
                "ApiId": {
                    "Ref": "AppSyncApiId"
                },
                "DataSourceName": "SomethingUpdatedDataSource",
                "FieldName": "somethingUpdated",
                "Kind": "UNIT",
                "TypeName": "Mutation",

                "RequestMappingTemplateS3Location": {
                    "Fn::Sub": [
                        "s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/resolvers/Mutation.somethingUpdated.req.vtl",
                        {
                            "S3DeploymentBucket": {
                                "Ref": "S3DeploymentBucket"
                            },
                            "S3DeploymentRootKey": {
                                "Ref": "S3DeploymentRootKey"
                            }
                        }
                    ]
                },
                "ResponseMappingTemplateS3Location": {
                    "Fn::Sub": [
                        "s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/resolvers/Mutation.somethingUpdated.res.vtl",
                        {
                            "S3DeploymentBucket": {
                                "Ref": "S3DeploymentBucket"
                            },
                            "S3DeploymentRootKey": {
                                "Ref": "S3DeploymentRootKey"
                            }
                        }
                    ]
                }
            }
        }
    },
    "Conditions": {
        "HasEnvironmentParameter": {
            "Fn::Not": [
                {
                    "Fn::Equals": [
                        {
                            "Ref": "env"
                        },
                        "NONE"
                    ]
                }
            ]
        },
        "AlwaysFalse": {
            "Fn::Equals": [
                "true",
                "false"
            ]
        }
    },
    "Outputs": {
        "EmptyOutput": {
            "Description": "An empty output. You may delete this if you have at least one resource above.",
            "Value": ""
        }
    }
}

/resolvers/Mutation.somethingUpdated.req.vtl

{
  "version": "2017-02-28",
  "payload": $util.toJson($context.arguments.fixtures)
}

/resolvers/Mutation.somethingUpdated.res.vtl

$util.toJson($ctx.result)

You would want to attach @aws_iam to your schema mutation (assuming cognito user pool is primary auth method), so your lambda with IAM execution role containing policy with appsync:GraphQL is allowed to call the mutation. in your schema:

type Mutation {
  somethingUpdated(something: [SomeInput!]): [Something!] @aws_iam @aws_cognito_user_pools
}

type Subscription {
  somethingDidUpdate: [Something!] @aws_subscribe(mutations:["somethingUpdated"]) @aws_cognito_user_pools
}

You then just call this mutation in your lambda. I personally use AppSynchClient for this, example can be found at https://github.com/aws-amplify/amplify-cli/issues/1678#issuecomment-538258341

SwaySway commented 5 years ago

Should you have any other questions related to this please feel free to comment below.

github-actions[bot] commented 3 years ago

This issue has been automatically locked since there hasn't been any recent activity after it was closed. Please open a new issue for related bugs.

Looking for a help forum? We recommend joining the Amplify Community Discord server *-help channels for those types of questions.