

# DynamoDB 低级 API
<a name="Programming.LowLevelAPI"></a>

Amazon DynamoDB *低级别 API* 是 DynamoDB 的协议级接口。在此级别，每个 HTTP(S) 请求的格式必须正确并带有有效的数字签名。

AWS SDK 代表您构建低级 DynamoDB API 请求并处理来自 DynamoDB 的响应。这可让您专注于应用程序逻辑而不是低级详细信息。不过，您仍可通过大致了解低级 DynamoDB API 的工作方式获益。

有关低级 DynamoDB API 的更多信息，请参阅[Amazon DynamoDB API 参考](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/)。

**注意**  
DynamoDB Streams 具有自己的低级别 API，此 API 独立于 DynamoDB 的低级别 API 且完全受 AWS SDK 支持。  
有关更多信息，请参阅 [将更改数据捕获用于 DynamoDB Streams](Streams.md)。有关低级 DynamoDB Streams API，请参阅[Amazon DynamoDB Streams API 参考](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Operations_Amazon_DynamoDB_Streams.html)。

低级 DynamoDB API 使用 JavaScript 对象表示法 (JSON) 作为通信协议格式。JSON 以层次结构的方式呈现数据，因此可同时传递数据值和数据结构。名称/值对以 `name:value` 格式定义。数据层次结构通过名称/值对的嵌套括号方式来定义。

DynamoDB 只将 JSON 用作传输协议而非存储格式。AWS SDK使用 JSON 将数据发送到 DynamoDB，DynamoDB 会通过 JSON 进行响应。DynamoDB 不会以 JSON 格式持久存储数据。

**注意**  
有关 JSON 的更多信息，请参阅 `JSON.org` 网站的[介绍 JSON](http://json.org)。

**Topics**
+ [

## 请求格式
](#Programming.LowLevelAPI.RequestFormat)
+ [

## 响应格式
](#Programming.LowLevelAPI.ResponseFormat)
+ [

## 数据类型描述符
](#Programming.LowLevelAPI.DataTypeDescriptors)
+ [

## 数值数据
](#Programming.LowLevelAPI.Numbers)
+ [

## 二进制数据
](#Programming.LowLevelAPI.Binary)

![\[DynamoDB 低级别 API 以及 AWS SDK 如何处理协议级别的请求和响应。\]](http://docs.aws.amazon.com/zh_cn/amazondynamodb/latest/developerguide/images/SDKSupport.DDBLowLevelAPI.png)


## 请求格式
<a name="Programming.LowLevelAPI.RequestFormat"></a>

DynamoDB 低级别 API 接受 HTTP(S) `POST` 请求作为输入。AWS SDK 为您构建这些请求。

假设您有一个名为 `Pets` 的表和一个包含 `AnimalType`（分区键）和 `Name`（排序键）的键架构。这两个属性的类型为 `string`。为了从 `Pets` 中检索项目，AWS SDK 构建了以下请求。

```
POST / HTTP/1.1
Host: dynamodb.<region>.<domain>;
Accept-Encoding: identity
Content-Length: <PayloadSizeBytes>
User-Agent: <UserAgentString>
Content-Type: application/x-amz-json-1.0
Authorization: AWS4-HMAC-SHA256 Credential=<Credential>, SignedHeaders=<Headers>, Signature=<Signature>
X-Amz-Date: <Date> 
X-Amz-Target: DynamoDB_20120810.GetItem

{
    "TableName": "Pets",
    "Key": {
        "AnimalType": {"S": "Dog"},
        "Name": {"S": "Fido"}
    }
}
```

请注意有关此请求的以下信息：
+ `Authorization` 标头包含 DynamoDB 验证请求所需的信息。有关更多信息，请参阅《Amazon Web Services 一般参考》中的[签署 AWS API 请求](https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html)和 [签名版本 4 签名流程](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html)**。
+ `X-Amz-Target` 标头包含 DynamoDB 操作的名称：`GetItem`。(这也是低级 API 版本附带的，此示例中为 `20120810`。)
+ 请求的负载 (正文) 包含 JSON 格式的操作参数。对于 `GetItem` 操作，参数为 `TableName` 和 `Key`。

## 响应格式
<a name="Programming.LowLevelAPI.ResponseFormat"></a>

收到请求后，DynamoDB 将处理请求并返回响应。对于前面显示的请求，HTTP(S) 响应负载包含来自操作的结果，如以下示例所示。

```
HTTP/1.1 200 OK
x-amzn-RequestId: <RequestId>
x-amz-crc32: <Checksum>
Content-Type: application/x-amz-json-1.0
Content-Length: <PayloadSizeBytes>
Date: <Date>
{
    "Item": {
        "Age": {"N": "8"},
        "Colors": {
            "L": [
                {"S": "White"},
                {"S": "Brown"},
                {"S": "Black"}
            ]
        },
        "Name": {"S": "Fido"},
        "Vaccinations": {
            "M": {
                "Rabies": {
                    "L": [
                        {"S": "2009-03-17"},
                        {"S": "2011-09-21"},
                        {"S": "2014-07-08"}
                    ]
                },
                "Distemper": {"S": "2015-10-13"}
            }
        },
        "Breed": {"S": "Beagle"},
        "AnimalType": {"S": "Dog"}
    }
}
```

此时，AWS SDK 会将响应数据返回给应用程序以供进一步的处理。

**注意**  
如果 DynamoDB 无法处理请求，它会返回 HTTP 错误代码和消息。AWS SDK 会以异常形式将这些错误代码和消息传播到应用程序。有关更多信息，请参阅 [DynamoDB 错误处理](Programming.Errors.md)。

## 数据类型描述符
<a name="Programming.LowLevelAPI.DataTypeDescriptors"></a>

低级 DynamoDB API 协议要求每个属性均带有数据类型描述符。*数据类型描述符*是告知 DynamoDB 如何解释每个属性的令牌。

[请求格式](#Programming.LowLevelAPI.RequestFormat)和[响应格式](#Programming.LowLevelAPI.ResponseFormat)中的示例说明了如何使用数据类型描述符。`GetItem` 请求为 `S` 类型的 `Pets` 键架构属性（`AnimalType` 和 `Name`）指定 `string`。`GetItem` 响应包含一个 *Pets* 项目，该项目带有 `string` (`S`)、`number` (`N`)、`map` (`M`) 和 `list` (`L`) 类型的属性。

以下是 DynamoDB 数据类型描述符的完整列表：
+ **`S`** – String
+ **`N`** – Number
+ **`B`** – Binary
+ **`BOOL`** – Boolean
+ **`NULL`** – Null
+ **`M`** – Map
+ **`L`** – List
+ **`SS`** – String Set
+ **`NS`** – Number Set
+ **`BS`** – Binary Set

下表展示了每个数据类型描述符的正确 JSON 格式。请注意，为了保持精度，数字以字符串表示，而布尔值和 null 则使用其原生 JSON 类型。


| 描述符 | JSON 格式 | 备注 | 
| --- | --- | --- | 
| S | \$1"S": "Hello"\$1 | 值是 JSON 字符串。 | 
| N | \$1"N": "123.45"\$1 | 值是字符串，而不是 JSON 数字。这样可以在不同的语言中保持精度。 | 
| B | \$1"B": "dGhpcyBpcyBhIHRlc3Q="\$1 | 值是 base64 编码的字符串。 | 
| BOOL | \$1"BOOL": true\$1 | 值是 JSON 布尔值（true 或 false），而不是字符串。 | 
| NULL | \$1"NULL": true\$1 | 值是 JSON 布尔值 true，表示 null。 | 
| M | \$1"M": \$1"Name": \$1"S": "Joe"\$1\$1\$1 | 值是采用属性名称/值对形式的 JSON 对象。 | 
| L | \$1"L": [\$1"S": "Red"\$1, \$1"N": "5"\$1]\$1 | 值是属性值类型的 JSON 数组。 | 
| SS | \$1"SS": ["Red", "Blue"]\$1 | 值是字符串类型的 JSON 数组。 | 
| NS | \$1"NS": ["1", "2.5"]\$1 | 值是数字字符串类型的 JSON 数组。 | 
| BS | \$1"BS": ["U3Vubnk=", "UmFpbnk="]\$1 | 值是 base64 编码字符串类型的 JSON 数组。 | 

**注意**  
 有关 DynamoDB 数据类型的详细描述，请参阅[数据类型](HowItWorks.NamingRulesDataTypes.md#HowItWorks.DataTypes)。

## 数值数据
<a name="Programming.LowLevelAPI.Numbers"></a>

不同的编程语言提供对 JSON 的不同级别的支持。在某些情况下，您可能会决定使用第三方库来验证和分析 JSON 文档。

一些第三方库基于 JSON 数字类型而构建，并提供它们自己的类型，例如 `int`、`long` 或 `double`。但是，DynamoDB 中的原生数字数据类型不能精确映射到其他数据类型，因此这些类型区别会造成冲突。此外，很多 JSON 库不能处理固定精度的数字，它们会将包含小数点的数字序列自动推断为双精度数据类型。

为了解决这些问题，DynamoDB 提供了不会造成数据丢失的单一数字类型。为了避免不必要的双精度值隐式转化，DynamoDB 将字符串用于数字值的数据传输。此方法可以灵活地更新属性值，同时能够保证排序语义的正确性，例如将“01”、“2”和“03”值按适当的顺序排列。

如果数字精度对您的应用程序十分重要，您应该先将数字值转换为字符串，然后再将它们传递到 DynamoDB。

## 二进制数据
<a name="Programming.LowLevelAPI.Binary"></a>

DynamoDB 支持二进制属性。但是，JSON 不支持在本地编码二进制数据。要在请求中发送二进制数据，您需要将其编码为 Base64 格式。收到请求后，DynamoDB 会将 Base64 数据解码回二进制数据。

DynamoDB 使用的 base64 编码方案在 Internet Engineering Task Force (IETF) 网站的 [RFC 4648](http://tools.ietf.org/html/rfc4648) 介绍。