Skip to content

Improving data queries handlers to AWS Lambda functions that are defined within the Amplify Gen 2 definition. #2976

@sbelbin

Description

@sbelbin

Environment information

System:
  OS: macOS 15.5
  CPU: (11) arm64 Apple M3 Pro
  Memory: 187.38 MB / 18.00 GB
  Shell: /bin/zsh
Binaries:
  Node: 23.7.0 - /opt/homebrew/bin/node
  Yarn: undefined - undefined
  npm: 11.4.2 - /opt/homebrew/bin/npm
  pnpm: undefined - undefined
NPM Packages:
  @aws-amplify/auth-construct: 1.8.1
  @aws-amplify/backend: 1.16.1
  @aws-amplify/backend-ai: Not Found
  @aws-amplify/backend-auth: 1.7.1
  @aws-amplify/backend-cli: 1.8.0
  @aws-amplify/backend-data: 1.6.1
  @aws-amplify/backend-deployer: 2.1.3
  @aws-amplify/backend-function: 1.14.1
  @aws-amplify/backend-output-schemas: 1.7.0
  @aws-amplify/backend-output-storage: 1.3.1
  @aws-amplify/backend-secret: 1.4.0
  @aws-amplify/backend-storage: 1.4.1
  @aws-amplify/cli-core: 2.2.1
  @aws-amplify/client-config: 1.8.0
  @aws-amplify/data-construct: 1.16.3
  @aws-amplify/data-schema: 1.21.1
  @aws-amplify/deployed-backend-client: 1.8.0
  @aws-amplify/form-generator: 1.2.4
  @aws-amplify/model-generator: 1.2.0
  @aws-amplify/platform-core: 1.10.0
  @aws-amplify/plugin-types: 1.11.0
  @aws-amplify/sandbox: 2.1.2
  @aws-amplify/schema-generator: 1.4.0
  @aws-cdk/toolkit-lib: 1.1.1
  aws-amplify: 6.15.5
  aws-cdk-lib: 2.214.0
  typescript: 5.9.2
No AWS environment variables
No CDK environment variables

Describe the feature

Within the data/resource.ts there is a query that has resolver handler & that handler is defined in the backend.ts as a AWS Lambda function.

The resolver handler defined as a AWS Lambda function, because it requires environment variables, which are the generated names of the DynamoDB tables. It does verifications and when all is good does scan and get commands to fetch entries from those tables.

amplify/data/resource.ts

  fetchRecordingsForUser: a
    .query()
    .arguments({
      username: a.string().required()
    })
    .returns(a.ref('Recording').array())
    .authorization(allow => [
      allow.groups(['user'])
    ])
    .handler(a.handler.function('fetchRecordingsForUserResolver')),

amplify/backend.ts

backend.fetchRecordingsForUserResolver.resources.lambda.addToRolePolicy(
  new iam.PolicyStatement({
    effect: iam.Effect.ALLOW,
    actions: [
      'dynamodb:GetItem',
      'dynamodb:Query',
      'dynamodb:Scan'
    ],
    resources: [
      backend.data.resources.tables["UserInstitutionAssociation"].tableArn,
      backend.data.resources.tables["Recording"].tableArn
    ]
  })
);

backend.fetchRecordingsForUserResolver.addEnvironment('USER_INSTITUTION_ASSOCIATION_TABLE_NAME', backend.data.resources.tables["UserInstitutionAssociation"].tableName);
backend.fetchRecordingsForUserResolver.addEnvironment('RECORDING_TABLE_NAME', backend.data.resources.tables["Recording"].tableName);

When invoking the fetchRecordingsForUser query, it reports that it cannot locate the associated AWS Lambda function.

Doing an experiment as to set query's handler string is that of the generated name AWS Lambda Function of the resolver hander, during AWS Amplify Gen 2's generating of the backend,

The result is that the resolver handler it behaved as expected.

  fetchRecordingsForUser: a
...
   .handler(a.handler.function('amplify-x9xx89xxxxx9xx-xx-fetchrecordingsforuserre-9x9x9xxxxXXx')),

For the record, I've tried defining these resolver handlers as part of the data, but that doesn't work since the handler still requires the environment variables as to set the name of the tables in DynamoDB.

Also, it's possible that I've overlooked other solutions and the many readings of this page https://docs.amplify.aws/react/build-a-backend/data/custom-business-logic/#step-2---configure-custom-business-logic-handler-code & working with several different AI agents we didn't get a solution that can be used in production context.

Having a mechanism allows set the query's .handler to the function's generated would be practical, such as using a placeholder mechanism (i.e. variable) whose value is set at a later stage in the generation.

Another choice is in the backend.ts to overwrite the query's handler later on, after the data/resource.ts.

Use case

Within an Amplify Gen 2 definitions (i.e data/resource.ts & backend.ts) there needs to be a way to pass the generated name of things such as tables, functions, & other backend resources...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions