AWS 无服务器 dynamodb - 删除项目不起作用

AWS serverless dynamodb - deleting item not working

我已经使用无服务器框架将无服务器应用程序部署到 aws。我有一个简单的待办事项应用程序。

TodoItem 看起来像这样:

export interface TodoItem {
  userId: string
  todoId: string
  createdAt: string
  name: string
  dueDate: string
  done: boolean
  attachmentUrl?: string
}

这就是我设置 dynamodb 的方式:

TodosDynamoDBTable:
      Type: 'AWS::DynamoDB::Table'
      Properties:
        AttributeDefinitions:
          - AttributeName: userId
            AttributeType: S
          - AttributeName: todoId
            AttributeType: S
          - AttributeName: createdAt
            AttributeType: S
        KeySchema:
          - AttributeName: todoId
            KeyType: HASH
          - AttributeName: createdAt
            KeyType: RANGE
        BillingMode: PAY_PER_REQUEST
        TableName: ${self:provider.environment.TODOS_TABLE}
        GlobalSecondaryIndexes:
          - IndexName: ${self:provider.environment.USER_ID_INDEX}
            KeySchema:
              - AttributeName: userId
                KeyType: HASH
              - AttributeName: createdAt
                KeyType: RANGE
            Projection:
              ProjectionType: ALL

我的删除待办事项 lambda 函数如下所示:

export const handler: APIGatewayProxyHandler = async (
  event: APIGatewayProxyEvent
): Promise<APIGatewayProxyResult> => {
  const todoId = event.pathParameters.todoId

  logger.info('Event: ', event)
  logger.info('Deleting a todo with id: ', todoId)
  // TODO: Remove a TODO item by id
  await deleteTodo(todoId, getUserId(event))

  return {
    statusCode: 204,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Credentials': true
    },
    body: null
  }
}

我正在删除这样的项目:

async deleteTodo(todoId: string, userId: string): Promise<any> {
    await this.docClient
      .delete({
        TableName: this.todosTable,
        Key: {
          userId,
          todoId
        }
      })
      .promise()
  }

但是,当我尝试删除一个项目时,我得到:

502 Bad Gateway

在 cloudwatch 日志中我可以看到我得到了这个错误:

2020-10-12T08:43:45.648Z 7ff99035-bf3d-4158-b311-1e6d7e73a6e5 ERROR Invoke Error {"errorType":"ValidationException","errorMessage":"The provided key element does not match the schema","code":"ValidationException","message":"The provided key element does not match the schema","time":"2020-10-12T08:43:45.629Z","requestId":"SRSL15PC9C3BN4RC4F5K3ERFNNVV4KQNSO5AEMVJF66Q9ASUAAJG","statusCode":400,"retryable":false,"retryDelay":49.16692204166978,"stack":["ValidationException: The provided key element does not match the schema"," at constructor.httpResponse (/var/task/src/lambda/http/webpack:/node_modules/aws-sdk/lib/protocol/json.js:47:1)"," at constructor.shift [as callListeners] (/var/task/src/lambda/http/webpack:/node_modules/aws-sdk/lib/sequential_executor.js:100:1)"," at constructor.doneCallback [as emit] (/var/task/src/lambda/http/webpack:/node_modules/aws-sdk/lib/sequential_executor.js:75:1)"," at constructor.call [as emitEvent] (/var/task/src/lambda/http/webpack:/node_modules/aws-sdk/lib/request.js:683:1)"," at constructor.emit (/var/task/src/lambda/http/webpack:/node_modules/aws-sdk/lib/request.js:22:1)"," at r.call [as runTo] (/var/task/src/lambda/http/webpack:/node_modules/aws-sdk/lib/state_machine.js:14:1)"," at runTo (/var/task/src/lambda/http/webpack:/node_modules/aws-sdk/lib/state_machine.js:26:1)"," at constructor.done (/var/task/src/lambda/http/webpack:/node_modules/aws-sdk/lib/request.js:38:1)"," at constructor.call (/var/task/src/lambda/http/webpack:/node_modules/aws-sdk/lib/request.js:685:1)"," at constructor.Error [as callListeners] (/var/task/src/lambda/http/webpack:/node_modules/aws-sdk/lib/sequential_executor.js:108:1)"]}

我怀疑我错误地为 dynamodb table 设置了散列键和范围键。我不确定为这样的 table?

设置的正确方法是什么

在您的 table 定义中,密钥由 todoIdcreatedAt 组成。但是,您的删除功能使用 todoIduserId 作为键。这不行。

当您已经拥有我认为是唯一的待办事项 ID 时,我不确定为什么需要用户 ID。如果像这样简单地从删除参数对象中的 Key 属性中删除 userId 是否有效?

async deleteTodo(todoId: string, userId: string): Promise<any> {
    await this.docClient
      .delete({
        TableName: this.todosTable,
        Key: {
          todoId
        }
      })
      .promise()
  }