开发者问题收集

想要创建一个可以访问 AWS Amplify DataStore 的 AWS Amplify 函数 (Lambda)

2024-02-08
292

我想创建一个可以访问 AWS DataStore 对象/模型的 AWS Amplify 函数 (Lambda)。

我一直无法让它工作。有没有人成功让它工作,可以提供一个代码示例?

我可以直接从 Lambda 访问 DynamoDB(我已成功设置所有权限等),但我想通过 DataStore 访问数据,因为这是我的应用程序访问和更新数据的方式,以实现数据一致性。

以下是我的代码(我必须删除机密内容)在 index.js 文件中的大致情况:

const { Amplify } = require('aws-amplify');
const { DataStore } = require('@aws-amplify/datastore');
const { Devices } = require('./models');

// Configure Amplify without browser-specific settings
Amplify.configure({
    aws_project_region: '(removed...)',
    aws_cognito_identity_pool_id: '(removed...)',
    aws_cognito_region: '(removed...)',
    aws_user_pools_id: '(removed...)',
    aws_user_pools_web_client_id: '(removed...)',
  });

/**
 * @type {import('@types/aws-lambda').APIGatewayProxyHandler}
 */
exports.handler = async (event) => {
    console.log(`EVENT: ${JSON.stringify(event)}`);

    process.on('unhandledRejection', (reason, promise) => {
        console.error('Unhandled Promise Rejection:', reason);
    });

        // this does not work
        
        await DataStore.start();

        const items = await DataStore.query(Devices);  // my tablename in DataStore
        console.log('Devices DataStore query results: ' + JSON.stringify(items));

        await DataStore.stop();
}

当我使用“amplify mock function function_name”运行此代码时,出现此错误:

Error querying DynamoDB or Sending Push: ReferenceError: window is not defined

谢谢, Alex

2个回答

AWS-amplify 库主要设计用于浏览器环境,其部分功能依赖于特定于浏览器的对象,如窗口和文档。但是,当您在 AWS Lambda 中运行代码时,您是在服务器端环境中操作,而这些特定于浏览器的对象不可用。 长话短说: window 在服务器端不可用

要在 AWS Lambda 等服务器端环境中与 AWS DataStore 交互,您不能像在客户端浏览器环境中那样直接使用 @aws-amplify/datastore 包。相反,您通常会使用适用于 JavaScript 的 AWS SDK 与 DataStore API 进行交互。

Oyinlade Demola
2024-02-08

如果您使用 AppSync,则“使用数据存储”会起作用,因为数据存储正在使用 AppSync。 在我的应用程序中,用户注册后,我会触发以下 Lambda。Lambda 将新用户创建为“数据存储表”中的新行。

您必须创建自定义突变: 我正在使用 Nodejs20.x。

  • 为了能够访问 node-fetch,您需要 创建一个层

  • 您在 aws Dashboard/appsync 中找到的 Graphqlendpoint。

  • 您在 aws Dahsboard/appsync/your_API 中找到的 api_key 并转到设置。
    在生产中,您应该使用 IAM 而不是 api_key!

我的 index.mjs 文件:

import { default as fetch, Request } from 'node-fetch';

const GRAPHQL_ENDPOINT = 'your_graphql_endpoint_here';
const GRAPHQL_API_KEY = 'your_graphQL_code_here';

//We want to use the "createUser" from the Appsync schema
//and create the following fields
let query =  `
  mutation CreateUserInput($input: CreateUserInput!) {
    createUser(input: $input) {
      id
      firstname
      lastname
      email
      description
    }
  }
`;

//The Event that comes from the postSignUp trigger, 
//which holds the info about the new user.
export const handler = async (event) => {
  
  let variables = {
    input: { 
      id: event.request.userAttributes.sub,
      firstname: event.request.userAttributes.name,
      lastname: event.request.userAttributes.family_name,
      email: event.request.userAttributes.email,
      description: event.request.userAttributes['custom:description'],
    }
  };


  const options = {
    method: 'POST',
    headers: {
      'x-api-key': GRAPHQL_API_KEY, //was set at the top
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ query, variables })
  };


  const request = new Request(GRAPHQL_ENDPOINT, options);


  try {
      //send the request to appsync
      let response = await fetch(request);
  } catch (error) {
       //could be smart to add logic here
    };
    return event;
  }

对于您的情况,您可以创建自定义查询,而不是进行自定义变异。

Sami
2024-04-10