DynamoDB get item TypeScript hell
Solution 1
I think you mix two different client definition files DynamoDB
and DynamoDB.DocumentClient
. While you're using the DynamoDB.DocumentClient
client, at the same time you're using the interface DynamoDB.Types.GetItemInput
from DynamoDB
.
You should use 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();
Solution 2
@ttulka's answer is perfect, but just to add on that I had the same issue and it really helped to spend 5 minutes to disambiguate the now MANY different ways of accessing DynamoDB from official AWS JS SDKs.
Reading this for 5 minutes is my answer, and it will all become clear to you after this;
https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/modules/_aws_sdk_lib_dynamodb.html
The tldr; is;
- know which AWS JS version you're using, whether its v2, or v3, and be mindful when you pull other samples from the internet that they might be applying to older versions - you should be able to tell based on the imports you're using, here are what the v3 imports look like:
import { DynamoDB } from "@aws-sdk/client-dynamodb"; // ES6 import
import { DynamoDBDocument, PutCommandInput } from "@aws-sdk/lib-dynamodb"; // ES6 import
- you likely want to use DocumentClient instead of raw DynamoDB where you need to specify the raw types of all attributes - in order to be successful doing this, your DynamoDB JS objects must be constructed in the right way (and the doc above explains exactly how)
- know if you're using the "bare bones" or the "full version" of DynamoDB, as you'll have access to more types/hints in TS if you're using the full version
- and you likely want to use client-dynamodb AND lib-dynanmodb, as the latter is an extra to the SDK to help make things easy (and it does)
Mingo
Updated on July 22, 2022Comments
-
Mingo almost 2 years
Can anyone explain how to use
GetItemInput
type when callingDocumentClient.get
?If I pass in an object of any type
get
works but if I try and strongly type the params object I get this error:ValidationException: The provided key element does not match the schema
Here is my lambda function code where I pass the params as type
any
:export const get: Handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => { console.log(event.pathParameters) if (!event.pathParameters) { throw Error("no path params") } const params: any = { Key: { id: event.pathParameters.id }, TableName: table } console.log(params) try { const result: any = await dynamoDb.get(params).promise() return { body: JSON.stringify(result.Item), statusCode: result.$response.httpResponse.statusCode } } catch (error) { console.log(error) return { body: JSON.stringify({ message: `Failed to get project with id: ${event.pathParameters!.id}` }), statusCode: 500 } } }
And here is my attempt to get it to work with type
GetItemInput
export const get: Handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => { console.log(event.pathParameters) if (!event.pathParameters) { throw Error("no path params") } const params: GetItemInput = { Key: { "id": { S: event.pathParameters.id } }, TableName: table } console.log(params) try { const result: any = await dynamoDb.get(params).promise() return { body: JSON.stringify(result.Item), statusCode: result.$response.httpResponse.statusCode } } catch (error) { console.log(error) return { body: JSON.stringify({ message: `Failed to get project with id: ${event.pathParameters!.id}` }), statusCode: 500 } } }
If I leave the
Key
as before ala:const params: GetItemInput = { Key: { id: event.pathParameters.id }, TableName: table }
Unsurprisingly I get a type error. But can't fathom how I can form my
Key
such that I dont get theValidationException
.Note the
id
field is of typeString
in theDynamoDB
. -
jcollum about 2 years"they might be applying to older versions" -- this is massively important when dealing with AWS SDKs. Their docs are routinely inadequate when it comes to explaining this.