DynamoDB получить элемент TypeScript hell

Кто-нибудь может объяснить, как использовать тип GetItemInput при вызове DocumentClient.get?

Если я передаю объект любого типа, get работает, но если я пытаюсь ввести объект params строго, я получаю эту ошибку:

ValidationException: The provided key element does not match the schema

Вот мой код лямбда-функции, где я передаю параметры как тип any:

export const get: Handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {

  console.info(event.pathParameters)
  if (!event.pathParameters) {
    throw Error("no path params")
  }

  const params: any = {
    Key: {
      id: event.pathParameters.id
    },
    TableName: table
  }

  console.info(params)
  try {
    const result: any = await dynamoDb.get(params).promise()
    return {
      body: JSON.stringify(result.Item),
      statusCode: result.$response.httpResponse.statusCode
    }

  } catch (error) {
    console.info(error)
    return {
      body: JSON.stringify({
        message: `Failed to get project with id: ${event.pathParameters!.id}`
      }),
      statusCode: 500
    }
  }
}

И вот моя попытка заставить его работать с типом GetItemInput

export const get: Handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {

  console.info(event.pathParameters)
  if (!event.pathParameters) {
    throw Error("no path params")
  }

  const params: GetItemInput = {
    Key: {
      "id": { S: event.pathParameters.id }
    },
    TableName: table
  }

  console.info(params)
  try {
    const result: any = await dynamoDb.get(params).promise()
    return {
      body: JSON.stringify(result.Item),
      statusCode: result.$response.httpResponse.statusCode
    }

  } catch (error) {
    console.info(error)
    return {
      body: JSON.stringify({
        message: `Failed to get project with id: ${event.pathParameters!.id}`
      }),
      statusCode: 500
    }
  }
}

Если я оставлю Key как раньше, аля:

const params: GetItemInput = {
  Key: {
    id: event.pathParameters.id
  },
  TableName: table
}

Неудивительно, что я получаю ошибку типа. Но не могу понять, как я могу сформировать свой Key так, чтобы не получить ValidationException.

Обратите внимание, что поле id имеет тип String в DynamoDB.

Где вы нашли GetItemInput? Мне это не кажется частью JS SDK. Я вижу его часть Ruby и Go SDK.

F_SO_K 14.03.2019 17:29

это мой оператор импорта, который работает, поэтому предположим, что он находится в типах данных Dynamo-DB

Mingo 14.03.2019 17:30

Эта ссылка предполагает, что это должно быть действительным... const params: GetItemInput = {Key: { "id": event.pathParameters.id}, TableName: table}, однако я получаю сообщение об ошибке типа, говорящее, что «тип« строка »не имеет атрибутов общего с типом 'AttributeValue'"

Mingo 14.03.2019 17:35

Я не вижу ссылки на это в ссылке?

F_SO_K 14.03.2019 17:37

SDK специально абстрагирует значения атрибутов и вместо этого использует собственный объект JSON (см. верхнюю часть страницы, на которую вы ссылаетесь). Я могу ошибаться, но я не думаю, что то, что вы пытаетесь, возможно.

F_SO_K 14.03.2019 17:38

поэтому я не должен использовать тип GetItemInput? Зачем иметь его в сигнатуре метода, если вы не можете его использовать. Если я импортирую типы, а затем нахожусь над методом, intellisense говорит мне, что он принимает в качестве аргумента GetItemInput, но, похоже, нет способа создать тот, который действительно работает, все, что я пытаюсь сделать, это использовать типы, которые метод говорит, что принимает свою подпись

Mingo 14.03.2019 17:40
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
6
12 699
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Я думаю, вы смешиваете два разных файла определения клиента DynamoDB и DynamoDB.DocumentClient. Пока вы используете клиент DynamoDB.DocumentClient, в то же время вы используете интерфейс DynamoDB.Types.GetItemInput из DynamoDB.

Вы должны использовать DynamoDB.DocumentClient.GetItemInput:

import {DynamoDB} from 'aws-sdk';
const dynamo = new DynamoDB.DocumentClient({apiVersion: '2012-08-10'});

...
const params: DynamoDB.DocumentClient.GetItemInput = {
    TableName: table,
    Key: {
        id: event.pathParameters.id
    }
};
const result = await this.dynamo.get(params).promise();

Ответ @ttulka идеален, но просто добавлю, что у меня была та же проблема, и это действительно помогло потратить 5 минут, чтобы устранить неоднозначность МНОЖЕСТВА различных способов доступа к DynamoDB из официальных SDK AWS JS.

Чтение этого в течение 5 минут - мой ответ, и вам все станет ясно после этого;

https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/modules/_aws_sdk_lib_dynamodb.html

TLDR; является;

  • Знайте, какую версию AWS JS вы используете, будь то v2 или v3, и помните, когда вы извлекаете другие образцы из Интернета, которые могут применяться к более старым версиям — вы должны быть в состоянии определить на основе импорта, который вы используя, вот как выглядит импорт v3:

import { DynamoDB } from "@aws-sdk/client-dynamodb"; // ES6 import
import { DynamoDBDocument, PutCommandInput } from "@aws-sdk/lib-dynamodb"; // ES6 import
  • вы, вероятно, захотите использовать DocumentClient вместо необработанного DynamoDB, где вам нужно указать необработанные типы всех атрибутов — для того, чтобы добиться успеха, ваши JS-объекты DynamoDB должны быть правильно сконструированы (и документ выше объясняет, как именно)
  • знать, используете ли вы «голые кости» или «полную версию» DynamoDB, так как у вас будет доступ к большему количеству типов/подсказок в TS, если вы используете полную версию
  • и вы, вероятно, захотите использовать client-dynamodb И lib-dynanmodb, так как последний является дополнением к SDK, чтобы упростить задачу (и это так)

Другие вопросы по теме