DynamoDB DataMapperをTypeScriptで使ってみた
DynamoDB DataMapperをTypeScriptで使ってみた:
2017年11月 AWSより、DynamoDB DataMapperというライブラリがDeveloper Previewで公開されました。
このDynamoDB DataMapperは、Javaで言うDynamoDB Mapperに近い感じで、クラスとDynamoDBに保存する型をマッピングすることができます。
またJavascriptの新しい記法を押さえているいい感じのライブラリなのですが、あまり日本語で紹介している記事がないので、ここではTypeScriptでの使い方を簡単に紹介していきます。
※本記事で紹介しているソースコードはTypeScript 2.9.2を使用しています。
DynamoDB DataMpperのGitHubには「DataMapperはアプリケーションのドメインクラスとDynamoDBに保存される型の相互運用を容易にします」と記載されています。
現在はv0.7.3まで公開されています。※2018年10月29日現在
まずはドメインクラスを宣言します。
@aws/dynamodb-data-mapper-annotationsパッケージを利用すると、
以下の例では
※dynamodb-data-mapper-annotationsを使う際は、tsconfig.jsonで
また、
@aws/dynamodb-data-mapper-annotationsは上記以外にも、
DynamoDBの書き込み、読み込みオペレーションの一部を紹介します。
putやGetなどのオペレーションには
DataMapperインスタンスの生成時に
第一引数は
Queryは少し特殊で、ES2018の機能である
まずはサンプルコードを見てみましょう。
第二引数にはKeyConditionの指定が可能です。上記の例では
さらにソートキーをKeyConditionExpressionで指定できます。
下記の例ではソートキーである
ここでは
DynamoDB.DocumentClientの場合だと、
のように
Queryにページネーションが発生する可能性がある場合は注意が必要です。
DynamoDBのQueryは1度に取得できるサイズは1MBまでという制限があるため、検索結果がそれを超える場合はレスポンスから取得できる
上記の例では1回目のqueryで取得した
今回はDynamoDB DataMapperを利用したDynamoDBの基本的な操作方法の一部をご紹介しました。
これから使おうと思っている方の一助になれば幸いです。
DynamoDB DataMapperは未だDeveloper Previewなので、正式リリースが待ち遠しいです!
概要
2017年11月 AWSより、DynamoDB DataMapperというライブラリがDeveloper Previewで公開されました。このDynamoDB DataMapperは、Javaで言うDynamoDB Mapperに近い感じで、クラスとDynamoDBに保存する型をマッピングすることができます。
またJavascriptの新しい記法を押さえているいい感じのライブラリなのですが、あまり日本語で紹介している記事がないので、ここではTypeScriptでの使い方を簡単に紹介していきます。
※本記事で紹介しているソースコードはTypeScript 2.9.2を使用しています。
DynamoDB DataMapper
DynamoDB DataMpperのGitHubには「DataMapperはアプリケーションのドメインクラスとDynamoDBに保存される型の相互運用を容易にします」と記載されています。現在はv0.7.3まで公開されています。※2018年10月29日現在
クラス宣言
まずはドメインクラスを宣言します。@aws/dynamodb-data-mapper-annotationsパッケージを利用すると、
Decoratorsを用いて、DynamoDBのTableとクラスのマッピングや、HashKeyやRangeKey、Attribute等とクラスプロパティをマッピングすることができます。以下の例では
id, createdAt, completedの3つのプロパティを持つドメインクラスMyModelを宣言しています。MyModel.ts
import {
attribute,
hashKey,
rangeKey,
table,
} from '@aws/dynamodb-data-mapper-annotations'
@table('MyModels')
export default class MyModel {
@hashKey()
id: string
@rangeKey({ defaultProvider: () => new Date() })
createdAt: Date
@attribute()
completed?: boolean
}
experimentalDecoratorsとemitDecoratorMetadataオプションをtrueにする必要があります。createdAtはDate型で宣言していますが、DynamoDBに格納する際はDataMapperがNumber型に変換して格納します。逆にGetなどで取得する際は、DataMapperがDate型に変換します。また、
defaultProvider: () => new Date()は、DynamoDBにオブジェクトを格納する際、プロパティがundefinedであれば指定したfunctionの結果を代入してくれます。@aws/dynamodb-data-mapper-annotationsは上記以外にも、
autoGeneratedHashKeyやversionAttributeなどの機能を提供しています。詳細はGitHubをご参照下さい。
オペレーション
DynamoDBの書き込み、読み込みオペレーションの一部を紹介します。putやGetなどのオペレーションには
DataMapperインスタンスを利用します。import { DataMapper } from '@aws/dynamodb-data-mapper'
const DynamoDB = require('aws-sdk/clients/dynamodb')
const mapper = new DataMapper({
client: new DynamoDB(),
tableNamePrefix: 'dev_'
})
tableNamePrefixオプションを指定すると、DataMapperは対象のクラス(この記事の例ではMyModel.ts)で宣言しているTable NameにPrefixを付けたものを利用します。
Get
const date = new Date(2018, 9, 1)
const result: MyModel = await mapper.get(Object.assign(new MyModel, {
id: 'A',
createdAt: date,
}))
getの戻り値はPromiseなので、awaitで受け取れます。第一引数は
Object.assignを使っていますが、newしたオブジェクトにプロパティを設定したものを渡しても大丈夫です。getの第二引数には、読み込み整合性などのオプションが指定できます。
Put
const result: MyModel = await mapper.put(Object.assign(new MyModel, {
id: 'A',
completed: true,
}))
getと同様にPromiseが返ってきます。putの第二引数には、条件式などのオプションが指定できます。
Query
Queryは少し特殊で、ES2018の機能であるAsync Iterationを利用します。まずはサンプルコードを見てみましょう。
const items = []
const query = mapper.query(MyModel, { id: 'A' })
for await (const item of query) {
items.push(item)
}
queryの返り値はAsync Iteratorのため、中身を取得する際はfor-await-of構文を利用することで一つずつアイテムを取得することができます。第二引数にはKeyConditionの指定が可能です。上記の例では
id: Aであるアイテムを取得しています。さらにソートキーをKeyConditionExpressionで指定できます。
下記の例ではソートキーである
createdAtを範囲指定で検索しています。const items = []
const query = mapper.query(MyModel, {
id: 'A',
createdAt: between(1514732400, 1543590000) // 2018-01-01 00:00:00 ~ 2018-12-01 00:00:00を指定
}
);
for await (const item of query) {
items.push(item)
}
@aws/dynamodb-expressionsパッケージに含まれるbetweenという関数を利用しています。DynamoDB.DocumentClientの場合だと、
const params = {
TableName: 'MyModels'
KeyConditionExpression: 'id = :id and createdAt between :startTime and :endTime',
ExpressionAttributeValues: {
':id': 'A',
':startTime': 1514732400,
':endTime': 1543590000
}
}
KeyConditonExpressionで式を記述したりExpressionAttributeValuesで値を指定しなければならなかったのですが、between関数を利用するとかなり簡素になりますね。@aws/dynamodb-expressionsには他にもequals, notEquals, lessThan, greaterThanなど色々な関数が用意されています。
Pagination
Queryにページネーションが発生する可能性がある場合は注意が必要です。DynamoDBのQueryは1度に取得できるサイズは1MBまでという制限があるため、検索結果がそれを超える場合はレスポンスから取得できる
lastEvaluatedKeyを利用して再度クエリをする必要があります。const items = []
const paginator = mapper.query(MyModel, { id: 'A' }).pages();
for await (const page of paginator) {
for (const item of page) {
items.push(item)
}
}
const newPaginator = mapper.query(MyModel, { id: 'A'},
{ startKey: paginator.lastEvaluatedKey })
.pages()
lastEvaluatedKeyを、2回目のqueryのstartKeyオプションに渡して、queryを再開しています。
まとめ
今回はDynamoDB DataMapperを利用したDynamoDBの基本的な操作方法の一部をご紹介しました。これから使おうと思っている方の一助になれば幸いです。
DynamoDB DataMapperは未だDeveloper Previewなので、正式リリースが待ち遠しいです!
コメント
コメントを投稿