この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、せーのです。今日はAWS SDK for PHPがバージョンアップしましたのでご紹介致します。
The DynamoDB Marshaler
新しい機能は2.7.7に「DynamoDB Marshaler」というクラスで実装されています。こちらは読んで字のごとくDynamoDBのitem形式のフォーマットでJSON形式のテキストとPHPのArray型の変換ができるようになるクラスです。例えばこんなJSONファイルがあるとします。
{
"id": "5432c69300594",
"name": {
"first": "Jeremy",
"middle": "C",
"last": "Lindblom"
},
"age": 30,
"phone_numbers": [
{
"type": "mobile",
"number": "5555555555",
"preferred": true
},
{
"type": "home",
"number": "5555555556",
"preferred": false
}
]
}
こちらはDynamoDBのitemに入るようなMap型[M]とList型[L]を表したJSONファイルとなります。こちらをMarshalerを使ってDynamoDBに取り込みます。
use Aws\DynamoDb\DynamoDbClient;
use Aws\DynamoDb\Marshaler;
$client = DynamoDbClient::factory(/* your config */);
$marshaler = new Marshaler();
$json = file_get_contents('/path/to/your/document.json');
$client->putItem([
'TableName' => 'YourTable',
'Item' => $marshaler->marshalJson($json)
]);
簡単ですね。MarshalerクラスのmarshalJson()メソッドに突っ込むだけです。印象的にはjson_decode()のDynamo版、という感じですね。このItemパラメータを見てみると
[
'id' => ['S' => '5432c69300594'],
'name' => ['M' => [
'first' => ['S' => 'Jeremy'],
'middle' => ['S' => 'C'],
'last' => ['S' => 'Lindblom'],
]],
'age' => ['N' => '30'],
'phone_numbers' => ['L' => [
['M' => [
'type' => ['S' => 'mobile'],
'number' => ['S' => '5555555555']
]],
['M' => [
'type' => ['S' => 'home'],
'number' => ['S' => '5555555556']
]],
]],
];
という感じになります。綺麗にArrayに入りました。ちなみにキーの[S]はString、[N]はNumericですね。この対応が入るまではこのSとかNとかをいちいち指定したJSONを作らないといけませんでしたが、これでようやくスッキリ!ですね。元のJSONに戻す時はunmarshalJson()メソッドを使用します。
$result = $client->getItem([
'TableName' => 'YourTable',
'Key' => ['id' => ['S' => '5432c69300594']]
]);
$json = $marshaler->unmarshalJson($result['Item']);
うん、こちらもスッキリ!ですね。
Marshaling a Native PHP Array
次に通常のPHPのArray型をDynamoDBのデータ型に落としこんだり、元に戻したりしてみましょう。こちらはそれぞれmarshalItem()メソッド、unmarshalItem()メソッドで実装されています。
$data = [
'id' => '5432c69300594',
'name' => [
'first' => 'Jeremy',
'middle' => 'C',
'last' => 'Lindblom',
],
'age' => 30,
'phone_numbers' => [
[
'type' => 'mobile',
'number' => '5555555555',
'preferred' => true
],
[
'type' => 'home',
'number' => '5555555556',
'preferred' => false
],
],
];
// Marshaling the data and putting an item.
$client->putItem([
'TableName' => 'YourTable',
'Item' => $marshaler->marshalItem($data)
]);
// Getting and item and unmarshaling the data.
$result = $client->getItem([
'TableName' => 'YourTable',
'Key' => ['id' => ['S' => '5432c69300594']]
]);
$data = $marshaler->unmarshalItem($result['Item']);
こちらは基本的にDynamoDbClient::formatAttributes()のアップグレードとなります。
注意事項
とこのように便利な機能が追加されたわけですが、注意して置かなければいけないこととしては「binary型[B]、set型[SS, NS, BS]には対応していない、ということです。こちらは型的にJSONに変換しづらい、ということがあるようです。こちらの型についてはバージョン3にて対応予定です。
非推奨クラス
今回のバージョンアップ対応にて同じようにArray型とDynamoDBItemの変換等をしていた
- Aws\DynamoDb\DynamoDbClient::formatValue()
- Aws\DynamoDb\DynamoDbClient::formatAttributes()
- Aws\DynamoDb\DynamoDbClient\Model\Attribute
- Aws\DynamoDb\DynamoDbClient\Model\Item
- Aws\DynamoDb\DynamoDbClient\Iterator\ItemIterator
これらのクラスにつきましてはバージョン3にて削除が予定されています。こちらのクラスを使っている方は今回新しく入ったMarshaler()クラスに移行することをお勧めします。
まとめ
いかがでしたでしょうか。DynamoDBのJSON対応自体は去年の10月にできてたのですが、先ほどのデータ型の指定をしなきゃいけない等、なかなか使いにくいものでしたが、これでひとまず使えるものになったのではないでしょうか。一度使ってみてください。