DynamoDB JSON 및 마샬링
DynamoDB API에서 원시 데이터를 처음 읽을 때는 JSON처럼 보이지 않습니다.
{"status": "open", "priority": 3} 같은 평범한 객체는 다음과 같이 돌아옵니다.
{"status": {"S": "open"}, "priority": {"N": "3"}}. 모든 값은
해당 유형의 이름을 지정하는 단일 키 개체입니다. 해당 래핑은 DynamoDB JSON이며 다음으로 변환됩니다.
이를 마샬링이라고 합니다.
이러한 래핑은 DynamoDB가 네트워크에서 유형을 명확하게 유지하는 방법입니다. 하지만 넘어진다 일반 JSON을 기대하는 사람이 있으면 손으로 쓰는 것은 오류가 발생하기 쉽습니다.
DynamoDB JSON이란 무엇입니까?
DynamoDB JSON은 DynamoDB가 사용하는 유형 태그가 지정된 연결 형식으로, 모든 값은 해당 유형의 이름을 지정하는 단일 키 객체(문자열의 경우 {"S": "open"}, 숫자의 경우 {"N": "3"})로 래핑됩니다. 일반 JSON을 JSON으로 변환하고 다시 변환하는 것을 마샬링이라고 합니다. 일반 JSON은 집합이나 이진수를 표현할 수 없고 DynamoDB 번호가 문자열로 전달되기 때문에 태그가 지정되지 않은 3는 모호해지기 때문에 유형을 명확하게 유지합니다.
- DynamoDB JSON은 모든 값에 해당 유형을 태그 지정합니다 — 문자열의 경우
{"S": "..."}, 숫자의 경우{"N": "..."}등입니다. - 마샬링 = 일반 JSON → DynamoDB JSON. 언마샬링 = 그 반대입니다.
- 숫자는 전선에 있는 문자열입니다 —
{"N": 3}가 아닌{"N": "3"}— 보존하기 위해 정밀도. - 유형 태그는 이미 모델링한 데이터 유형 시스템입니다: S, N, B, BOOL, NULL, L, M, SS, NS, BS.
- 직접 작성하지 마세요. SDK의 문서 클라이언트(또는 변환기)는 다음을 위해 마샬링됩니다. 당신; 표현식을 디버깅하거나 작성할 때만 수동으로 수행하십시오.
문제: 일반 JSON으로는 충분하지 않습니다
JSON에는 정확히 세 가지 스칼라 종류(문자열, 숫자, 부울)와 null, 배열 및
객체. DynamoDB에는 이진수와 세 가지 세트 유형(문자열 세트, 숫자 세트,
바이너리 세트) JSON에서는 전혀 표현할 수 없습니다. 그리고 DynamoDB 번호가 전송되기 때문에
문자열로서 태그가 지정되지 않은 3는 모호합니다. 게다가 JSON은 목록과 문자열을 구분할 수 없습니다.
설정합니다.
따라서 DynamoDB는 JSON을 있는 그대로 저장할 수 없습니다. 각 값의 정확한 유형이 명시되어 있어야 합니다. 명시적으로. 유형 설명자는 모든 요청에 대해 손실 없이 이를 수행하는 방법입니다. 응답.
인코딩 작동 방식
모든 속성 값은 키가 유형 설명자인 단일 키 객체가 됩니다.
| 설명자 | 유형 | 예 |
|---|---|---|
S | 문자열 | {"S": "open"} |
N | 숫자(문자열) | {"N": "3"} |
B | 바이너리 | {"B": "dGV4dA=="} |
BOOL | 부울 | {"BOOL": true} |
NULL | 널 | {"NULL": true} |
L | 목록 | {"L": [{"S": "a"}, {"N": "1"}]} |
M | 지도 | {"M": {"k": {"S": "v"}}} |
SS / NS / BS | 문자열/숫자/바이너리 세트 | {"SS": ["a", "b"]} |
목록과 지도는 동일한 설명자를 아래로 내포하므로 깊게 구조화된 항목입니다. 깊게 감싸게 됩니다. 숫자는 의도적으로 문자열처럼 와이어를 타고 이동합니다. DynamoDB는 JSON 숫자( IEEE-754 double, ~15–17 유효 숫자)은 조용히 반올림됩니다. 이것들은 동일합니다 data types 당신이 모델로 삼고 있는 것; DynamoDB JSON은 명시적입니다. on-the-wire 양식에 정의되어 있습니다. AWS low-level API reference.
실제 예제: 감사 로그 항목
앱에서 작성하는 일반 JSON:
{
"actor": "u-204",
"action": "ticket.close",
"ticketId": 8842,
"tags": ["billing", "urgent"],
"redacted": false
}API용 DynamoDB JSON으로 마샬링됨:
{
"actor": {"S": "u-204"},
"action": {"S": "ticket.close"},
"ticketId": {"N": "8842"},
"tags": {"SS": ["billing", "urgent"]},
"redacted": {"BOOL": false}
}이 항목 뒤에 있는 선택 사항에 유의하십시오. ticketId는 문자열 값을 사용하여 N이 되었습니다.
목록이 아닌 문자열 세트(SS)로서의 tags는 직접 만든 모델링 선택입니다.
일반 JSON을 제공하는 일반 변환기는 L를 방출합니다. JSON 배열은 순서가 지정되어 있고
반복하고 SS는 중복을 제거하고 순서가 지정되지 않습니다. tags이 SS이어야 하는지 아니면 L이어야 하는지는
변환기가 전화를 모델링할 수 없는 이유가 바로 이 때문입니다.
인코딩이 중요합니다.
DynoTable에서 변환
손으로 읽거나 쓸 필요가 거의 없습니다. 일반 JSON을 DynamoDB JSON converter를 사용하여 마샬링하고 다시 돌아옵니다. 요청을 수집할 때 DynamoDB expression builder는 올바르게 방출합니다. 표현식과 함께 정렬된 속성-값 맵입니다. 앱 자체에서는 DynoTable 항목을 일반적이고 읽을 수 있는 값으로 표시하고 쓰기 시 정리합니다.

함정과 다음 단계
- 숫자는 DynamoDB JSON의 문자열입니다 —
{"N": "3"}. 인용 문제; 하지마 숫자만 내보냅니다. - 세트와 목록은 모델링 결정입니다 인코딩을 통해 표시됩니다. 선택 의도적으로(data types 참조).
- 앱 코드에서 직접 마샬링하는 것보다 SDK 문서 클라이언트를 선호합니다. 매뉴얼 예약 디버깅 및 표현식을 위한 DynamoDB JSON.
- 키가 아닌 속성에는 빈 문자열이 허용됩니다(2020년부터). 그러나 여전히 거부됩니다. 테이블 및 인덱스 키에 대해 역사적으로 잘못된 도구를 사용했습니다. 극단적인 경우를 검증합니다.
유형 태그를 눈으로 디코딩하는 대신 일반 값으로 항목을 찾아보고 싶으십니까? Download DynoTable 데이터로 직접 작업할 수 있습니다.
하위 수준 클라이언트 대 문서 클라이언트
AWS SDK는 두 가지 계층을 제공합니다.
| 레이어 | 입력 형태 | 누가 마샬링합니까 |
|---|---|---|
@aws-sdk/client-dynamodb (낮은 수준) | DynamoDB JSON AttributeValue 지도 | 귀하의 코드 또는 도우미 |
@aws-sdk/lib-dynamodb (문서) | 일반 JS 객체 | 보내기/받기 시 SDK |
애플리케이션 코드는 PutItem/GetItem에 대한 문서 클라이언트로 기본 설정되어야 합니다.
직접 작성하면 낮은 수준의 지도에 접근할 수 있습니다.
update expressions 또는 도서관에서 예상하는 경우
입력된 속성 값.
표현식 속성 값도 마샬링됩니다.
ConditionExpression, UpdateExpression 및 FilterExpression 자리 표시자
(:val, :inc)는 ExpressionAttributeValues의 마샬링된 값에 매핑됩니다.
":status": {"S": "open"}
":count": {"N": "1"}불일치 — 하위 수준 클라이언트에서 S 래퍼 없이 "open" 전송 —
ValidationException를 반환합니다. 는
expression builder는 지도를 함께 내보냅니다.
자리 표시자와 유형이 정렬된 상태로 유지되도록 표현식 문자열입니다.
다음과 충돌하는 속성 이름
reserved words 사용
대신 ExpressionAttributeNames (#st); 검사기 도구는 별칭을 출력합니다.
지도를 붙여넣을 준비가 되었습니다.
테스트에서 Unmarshal 놀라움
마샬링으로 인한 일반적인 테스트 실패:
- 빈 세트 — DynamoDB는 비어 있는
SS/NS/BS를 거부합니다. 속성을 생략하다 대신. - Float in
N—"3.14"를 JSON 숫자가 아닌 문자열로 전송합니다. - 노드의 바이너리 — 문서 클라이언트의
Uint8Array; 원시 JSON의 base64. - 정의되지 않은 속성 — 문서 클라이언트 스트립
undefined; 낮은 수준의 클라이언트 잘못된 페이로드를 보낼 수 있습니다.
Lambda가 원시 API 응답을 기록할 때 하나의 항목을 DynamoDB JSON converter - 읽을 수 있는 일반 JSON 설비와 비교하기 전에.
태그 지정이 크기에 미치는 영향
모든 유형 래퍼는 바이트를 추가합니다. 필드별로 마샬링된 플랫 JSON 객체가 증가합니다.
속성 이름에 따라 약 30~40% — 인플레이션이 발생합니다.
item size 및 RCU/WCU 반올림. 대형 지도
짧은 속성 이름을 사용하면 오버헤드가 상각됩니다. 작은 부울 플래그는 여전히 비용을 지불합니다
해당 키 이름에 {"BOOL":true}를 더한 것입니다.
마샬링된 항목을 대량 로드하기 전에 item-size calculator 그래서 일괄 쓰기 예기치 않게 16MB 요청 제한을 초과하지 않습니다.
DynoTable의 두 가지 보기
항목 편집기는 매일 보이지 않게 정리합니다. 일반 값을 편집하고, 전송 시 마샬링을 커밋합니다. 복사된 생산 품목을 디버깅할 때 CloudWatch 로그, DynamoDB JSON 보기로 전환하여 정확한 태그를 확인한 후 다시 전환 편집을 위해 일반 JSON으로. 내보내기 작업은 티켓에 대한 표현 중 하나를 복사합니다. 그리고 테스트 케이스.


