微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从 Amplify 中的 Lambda 函数访问存储的问题

如何解决从 Amplify 中的 Lambda 函数访问存储的问题

我想做什么?

我想创建 REST API,从我的 DynamoDB 表中返回数据,该表由 GraphQL 模型创建。

我做了什么

  1. 创建 GraphQL 模型
type Public @model {
  id: ID!
  name: String!
}
  1. 使用可访问我的 PublicTable 的 Lambda 函数创建 REST API
$ amplify add api
? Please select from one of the below mentioned services: REST
? Provide a friendly name for your resource to be used as a label for this category in the project: rest
? Provide a path (e.g.,/book/{isbn}): /items
? Choose a Lambda source Create a new Lambda function
? Provide an AWS Lambda function name: listPublic
? Choose the runtime that you want to use: NodeJS
? Choose the function template that you want to use: Hello World

Available advanced settings:
- Resource access permissions
- Scheduled recurring invocation
- Lambda layers configuration

? Do you want to configure advanced settings? Yes
? Do you want to access other resources in this project from your Lambda function? Yes
? Select the category storage
? Storage has 8 resources in this project. Select the one you would like your Lambda to access Public:@model(appsync)
? Select the operations you want to permit for Public:@model(appsync) create,read,update,delete

You can access the following resource attributes as environment variables from your Lambda function
        API_MYPROJECT_GRAPHQLAPIIDOUTPUT
        API_MYPROJECT_PUBLICTABLE_ARN
        API_MYPROJECT_PUBLICTABLE_NAME
        ENV
        REGION
? Do you want to invoke this function on a recurring schedule? No
? Do you want to configure Lambda layers for this function? No
? Do you want to edit the local lambda function Now? No
Successfully added resource listPublic locally.

Next steps:
Check out sample function code generated in <project-dir>/amplify/backend/function/listPublic/src
"amplify function build" builds all of your functions currently in the project
"amplify mock function <functionName>" runs your function locally
"amplify push" builds all of your local backend resources and provisions them in the cloud
"amplify publish" builds all of your local backend and front-end resources (if you added hosting category) and provisions them in the cloud
Succesfully added the Lambda function locally
? Restrict API access No
? Do you want to add another path? No
Successfully added resource rest locally
  1. 编辑我的 Lambda 函数
/* Amplify Params - DO NOT EDIT
    API_MYPROJECT_GRAPHQLAPIIDOUTPUT
    API_MYPROJECT_PUBLICTABLE_ARN
    API_MYPROJECT_PUBLICTABLE_NAME
    ENV
    REGION
Amplify Params - DO NOT EDIT */

const AWS = require("aws-sdk");
const region = process.env.REGION

AWS.config.update({ region });

const docclient = new AWS.DynamoDB.DocumentClient();

const params = {
    TableName: "PublicTable"
}

async function listItems(){
    try {
      const data = await docclient.scan(params).promise()
      return data
    } catch (err) {
      return err
    }
}

exports.handler = async (event) => {
    try {
        const data = await listItems()
        return { body: JSON.stringify(data) }
      } catch (err) {
        return { error: err }
    }
};
  1. 推送我的更新
$ amplify push
  1. 打开我的 REST API 端点 /items
{
  "message": "User: arn:aws:sts::829736458236:assumed-role/myprojectLambdaRolef4f571b-dev/listPublic-dev is not authorized to perform: dynamodb:Scan on resource: arn:aws:dynamodb:us-east-1:8297345848236:table/Public-ssrh52tnjvcdrp5h7evy3zdldsd-dev","code": "AccessDeniedException","time": "2021-04-21T21:21:32.778Z","requestId": "JOA5KO3GVS3QG7RQ2V824NGFVV4KQNSO5AEMVJF66Q9ASUAAJG","statusCode": 400,"retryable": false,"retryDelay": 28.689093010346657
}

问题

  1. 我做错了什么?
  2. 我如何访问我的表,为什么我在创建它时没有得到它?
  3. 为什么需要 API_MYPROJECT_PUBLICTABLE_NAME 和其他常量?

解决方法

决定

问题出在 NodeJS 版本或 amplify-cli 版本上。更新 amplify-cli 并在 14.16.0 版本上安装节点后,一切正常。 我还将表的名称更改为 Amplify 为我们创建的名称,尽管此代码之前不起作用。代码变成这样:

/* Amplify Params - DO NOT EDIT
    API_MYPROJECT_GRAPHQLAPIIDOUTPUT
    API_MYPROJECT_PUBLICTABLE_ARN
    API_MYPROJECT_PUBLICTABLE_NAME
    ENV
    REGION
Amplify Params - DO NOT EDIT */

const AWS = require("aws-sdk");
const region = process.env.REGION
const tableName = process.env.API_MYPROJECT_PUBLICTABLE_NAME

AWS.config.update({ region });

const docClient = new AWS.DynamoDB.DocumentClient();

const params = {
    TableName: tableName
}

async function listItems(){
    try {
      const data = await docClient.scan(params).promise()
      return data
    } catch (err) {
      return err
    }
}

exports.handler = async (event) => {
    try {
        const data = await listItems()
        return { body: JSON.stringify(data) }
      } catch (err) {
        return { error: err }
    }
};

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。