#✅ - Passing table name to appsync js resolver using environment variables

17 messages · Page 1 of 1 (latest)

indigo ocean
#

I need to write a custom query resolver that consists of a BatchGetItem dynamodb operation where i need to pass the table name. Now i'm stuck getting the table name passed to the resolver using environment variables.

Here is what my resolver looks like:

handler.ts

export function request(
    ctx: Context<Schema["customListOrganizations"]["args"]>
): DynamoDBBatchGetItemRequest {
 
    console.log(ctx.env.ORGANIZATION_TABLE);

    ...

    return {
        operation: "BatchGetItem",
        tables: {
            // I need to pass the table name using environment variables
            [ctx.env.ORGANIZATION_TABLE]: {
                keys: organizationIDs,
            },
        },
    };
}

I tried passing the table name as an environment variable in backend.ts but i'm getting a circular dependency error.

backend.ts

backend.data.resources.cfnResources.cfnGraphqlApi.environmentVariables = {
    ORGANIZATION_TABLE: backend.data.resources.tables.Organization.tableName,
};

Does anybody have a solution? Thanks in advance!

versed rapids
#

Same problema here

frigid apex
#

I also have the same issue

granite comet
#

Same issue for me too

glacial dagger
versed rapids
glacial dagger
#

Overlooked that detail there. 🙃

Put me down also as one who will be facing this issue.

versed rapids
#

I found an alternative if you are trying to implement Transact or Batch commands.

import { defineFunction } from '@aws-amplify/backend'
import { custom } from '../../../amplify_outputs.json'

export const createProductFunction = defineFunction({
  name: 'createProductResolver',
  entry: './resolvers/create-product.js',
  environment: custom
})

In data source, add your function to data.

export const data = defineData({
  schema,
  functions: {
    createProductFunction
  }
})

export it in backend too and add your table names in environment:

const backend = defineBackend({
  auth,
  data,
  storage,
  createProductFunction,
})

backend.addOutput({
  custom: Object.fromEntries(
    Object.entries(backend.data.resources.tables).map(([name, table]) => [
      `${name.toUpperCase()}_TABLE_NAME`,
      table.tableName,
    ])
  ),
})

Finaly create a handler function:

import { TransactWriteItemsCommand, DynamoDBClient } from '@aws-sdk/client-dynamodb'
import { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb'
import { convertToAttr } from '@aws-sdk/util-dynamodb'
import { randomUUID } from 'crypto'

const client = new DynamoDBClient({})
const docClient = DynamoDBDocumentClient.from(client)

export const handler = async (event: any) => {
  const dateNow = new Date().toISOString()

  const trasactObj = new TransactWriteItemsCommand({
    TransactItems:[
      {
        Put: {
          TableName: env.PRODUCT_TABLE_NAME,
          Item: {
            id: convertToAttr(randomUUID()),
            image_url: convertToAttr('urltest'),
            description: convertToAttr('description test'),
            price: convertToAttr('22,99'),
            createdAt: convertToAttr(dateNow),
            updatedAt: convertToAttr(dateNow),
            __typename: convertToAttr('Product')
          },
        }
      }
  ]})

  return trasactObj.input
} 
glacial dagger
#

Weird. Seems that even passing the apiId would give a circular dependency error:

  data.resources.cfnResources.cfnGraphqlApi.environmentVariables = {
    API_ID: data.resources.cfnResources.cfnGraphqlApi.attrApiId,
  };

The table name follows the format of <<ModelName>>-<<API_ID>>-<<ENV_NAME_IF_PRESENT_OTHERWISE_NONE>>. If we could pass the API id and the ENV parameter we could construct the table name without formally depending on the table resource.

versed rapids
glacial dagger
#

I raised the issue in Office Hours. The response is here:

#844970815426658334 message

bronze brook
viral novaBOT
#

✅ - Passing table name to appsync js resolver using environment variables

viral novaBOT
indigo ocean
#

@bronze brook @pearl willow Have you even read the issue / conversation here?

pearl willow
#

Sorry about that. The correct answer here is we are working on a way to allow you to access the table names in resolvers by constructing them from the stash.

Please track this amplify/docs PR for updates:
https://github.com/aws-amplify/docs/pull/8145

GitHub

Description of changes:
Add page for batch ddb operations.
Related GitHub issue #, if available: aws-amplify/amplify-category-api#408 (comment)
Instructions
If this PR should not be merged upon app...