#環境構築
今回使うものはこちら
- Docker
- Dynamodb local
- AWS CLI バージョン 2
- vcpkg
- AWS SDK for C++
また、C++ のビルド環境には VC++ を使用します。
##Docker の導入
Docker は、コンテナを用いてアプリケーションをすばやく構築、テスト、デプロイできるソフトウェアプラットフォームです。
###ダウンロード
Docker のサイトからインストーラをダウンロードしましょう。
※この記事では、Docker Desktop for Windows を使用します。
###インストール
Docker Desktop requires Windows 10 Pro/Enterprise (16299+) or Windows 10 Home (18362.1040+).
インストール中に、上のようなエラーメッセージが出る場合は、Windows Update を確認してみてください。アップデート後に、もう一度インストールを試してみましょう。
WSL 2 installation is imcomplete.
上のダイアログメッセージが出る場合は、Linux カーネル更新プログラムのインストールが必要です。以下からパッケージをダウンロードしましょう。
###バージョン確認
コマンドラインからDocker のバージョンを確認してみましょう。インストールに成功していれば、以下のような出力が得られるはずです。
> docker --version
Docker version 20.10.0, build 7287ab3
##DynamoDB local の導入
ダウンロード可能なバージョンの Amazon DynamoDB (DynamoDB local)では、DynamoDB ウェブサービスにアクセスせずに、アプリケーションを開発してテストすることができます。代わりに、データベースはコンピュータ上で自己完結型となります。
###イメージを取得する
Docker を使って、DynamoDB local イメージを取得しましょう。
Amazon が公開している DynamoDB local のDocker イメージがありますので、
docker pull
コマンドを使って取得します。
> docker pull amazon/dynamodb-local
###コンテナを起動する
Docker を使って、DynamoDB local を起動しましょう。
docker run
コマンドを使って起動します。
> docker run -p 8000:8000 amazon/dynamodb-local
これで DynamoDB local のコンテナが起動しました。わかりやすくポート番号は8000を使用しました。
###コンテナを確認する
docker ps
コマンドを使うと、現在起動しているコンテナのリストが出力されます。
> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
607c8a202aac amazon/dynamodb-local "java -jar DynamoDBL…" 2 seconds ago Up 7 seconds 0.0.0.0:8000->8000/tcp frosty_goldstine
###コンテナを終了する
docker kill
コマンドを使うと、起動しているコンテナを終了させることができます。このとき、コンテナIDを指定します。
> docker kill 607c8a202aac
##AWS CLI バージョン 2 の導入
AWS CLI には、DynamoDB local を操作するためのコマンドラインツールが含まれています。
※今回はテーブル情報の読み出しのためだけに利用したいと思います。(C++ からのリクエストが正しく通っているかを確認するため。)
事前にインストールしておきましょう。
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2-windows.html
###初回設定
1度だけこちらの4項目を設定しておきましょう。
それぞれ、設定内容はダミーでもよいですが、忘れないように覚えておく必要があります。もし忘れてしまったら設定しなおしましょう。
> aws configure
AWS Access Key ID [****************XXXX]: (ローカルで使用するのでダミーのキーIDでよい)
AWS Secret Access Key [****************XXXX]: (ローカルで使用するのでダミーのアクセスキーでよい)
Default region name [us-west-2]:(ローカルで使用するのでダミーのリージョンでよい)
Default output format [json]:
###動作確認(DynamoDB local のテーブルリストを取得する)
DynamoDB local にアクセスして、動作確認をしてみましょう。
まだテーブルを作っていないので、以下のような JSON が取得できるはずです。
> aws dynamodb list-tables --endpoint-url http://localhost:8000
{
"TableNames": []
}
##AWS SDK for C++ の導入
今回は、C++ からDynamoDB local にアクセスするので、AWS SDK for C++ というライブラリを使用します。
###vcpkg をインストールする
vcpkg は、C++ のコマンド ライン パッケージ マネージャーです。 これにより、Windows、Linux、および macOS でのサードパーティ ライブラリの取得とインストール作業を大幅に簡素化できます。
github から取得し、ブートストラップを実行しましょう。
> git clone https://github.com/microsoft/vcpkg
> ./vcpkg/bootstrap-vcpkg.bat
###AWS SDK for C++ を取得する
vcpkg を使って、ライブラリを取得しましょう。
> ./vcpkg/vcpkg install aws-sdk-cpp:x64-windows
###VC++ にインテグレートする
vcpkg を VC++ にインテグレートします。
これによって、先ほどダウンロードしたAWS SDK for C++ のためのインクルードパスの設定や、.lib のリンクを自動で行ってくれるようになります。
> ./vcpkg/vcpkg integrate install
※ただし、コーディング中のインテリセンスを働かせるためには、手動でインクルードパスを通す必要がありました。
また、インテグレートを解除したい場合は、以下のコマンドを使います。
> ./vcpkg/vcpkg integrate remove
#コーディング
主要なデータベース操作と、対応する AWS SDK for C++ の関数名を挙げておきます。
AWS のサイトにもサンプルコードがあるので、参考にしてみてください。
用途 | 関数名 |
---|---|
テーブル追加 | Aws::DynamoDB::DynamoDBClient::CreateTable |
テーブル削除 | Aws::DynamoDB::DynamoDBClient::DeleteTable |
アイテム取得 | Aws::DynamoDB::DynamoDBClient::GetItem |
アイテム追加 | Aws::DynamoDB::DynamoDBClient::PutItem |
アイテム更新 | Aws::DynamoDB::DynamoDBClient::UpdateItem |
アイテム削除 | Aws::DynamoDB::DynamoDBClient::DeleteItem |
C++ Code Samples for Amazon DynamoDB
https://docs.aws.amazon.com/code-samples/latest/catalog/code-catalog-cpp-example_code-dynamodb.html
##テーブル作成(create-table)
#include <aws/core/Aws.h>
#include <aws/core/utils/Outcome.h>
#include <aws/dynamodb/DynamoDBClient.h>
#include <aws/dynamodb/model/AttributeDefinition.h>
#include <aws/dynamodb/model/CreateTableRequest.h>
#include <aws/dynamodb/model/KeySchemaElement.h>
#include <aws/dynamodb/model/ProvisionedThroughput.h>
#include <aws/dynamodb/model/ScalarAttributeType.h>
#include <iostream>
// ここで、予め設定しておいたアクセスキーを使います
const Aws::String AWS_ACCESS_KEY_ID = "XXXXXXXXXXXXXXXXXXXX";
const Aws::String AWS_SECRET_ACCESS_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
Aws::SDKOptions options;
Aws::InitAPI(options);
// 作成したいテーブルの名前を決める
const Aws::String table("Game");
// ここで、予め設定しておいたリージョン名を使います
const Aws::String region("us-west-2");
// エンドポイントを指定する
Aws::Client::ClientConfiguration clientConfig;
clientConfig.requestTimeoutMs = 1000;
clientConfig.region = region;
clientConfig.endpointOverride = "http://localhost:8000";
const Aws::DynamoDB::DynamoDBClient dynamoClient(Aws::Auth::AWSCredentials(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY), clientConfig);
// テーブル作成リクエスト
Aws::DynamoDB::Model::CreateTableRequest req;
Aws::DynamoDB::Model::AttributeDefinition haskKey;
// "Name"という名前の属性を定義する、"Name"は文字列型である
haskKey.SetAttributeName("Name");
haskKey.SetAttributeType(Aws::DynamoDB::Model::ScalarAttributeType::S);
req.AddAttributeDefinitions(haskKey);
// "Name" をハッシュキー(パーティションキー)として扱うようにスキーマを定義する
Aws::DynamoDB::Model::KeySchemaElement keyscelt;
keyscelt.WithAttributeName("Name").WithKeyType(Aws::DynamoDB::Model::KeyType::HASH);
req.AddKeySchema(keyscelt);
// 適当なキャパシティユニットを設定する
Aws::DynamoDB::Model::ProvisionedThroughput thruput;
thruput.WithReadCapacityUnits(5).WithWriteCapacityUnits(5);
req.SetProvisionedThroughput(thruput);
// テーブル名を指定する
req.SetTableName(table);
// テーブル作成リクエストをDynamoDB local に送信する(この関数はブロックするので注意!)
const Aws::DynamoDB::Model::CreateTableOutcome& result = dynamoClient.CreateTable(req);
if (result.IsSuccess())
{
std::cout << "Table \"" << result.GetResult().GetTableDescription().GetTableName() <<
" created!" << std::endl;
}
else
{
std::cout << "Failed to create table: " << result.GetError().GetMessage();
}
Aws::ShutdownAPI(options);
AWS CLI を使って、テーブルが作成できているかの確認をしてみましょう。
うまく作成できていれば、以下のような JSON が取得できるはずです。
> aws dynamodb list-tables --endpoint-url http://localhost:8000
{
"TableNames": [
"Game"
]
}
アイテム追加(put-item)
#include <aws/core/Aws.h>
#include <aws/core/utils/Outcome.h>
#include <aws/core/auth/AWSCredentialsProvider.h>
#include <aws/dynamodb/DynamoDBClient.h>
#include <aws/dynamodb/model/AttributeDefinition.h>
//#include <aws/dynamodb/model/CreateTableRequest.h>
#include <aws/dynamodb/model/PutItemRequest.h>
#include <aws/dynamodb/model/PutItemResult.h>
#include <iostream>
//(途中省略...)
Aws::DynamoDB::Model::PutItemRequest req;
// 対象のテーブル名を指定する
req.SetTableName(table);
Aws::DynamoDB::Model::AttributeValue av;
// "Name" が 文字列型"Switch"
av.SetS("Switch");
req.AddItem("Name", av);
// "State" が 文字列型"off"
av.SetS("off");
req.AddItem("State",av);
// アイテム追加リクエストをDynamoDB local に送信する(この関数はブロックするので注意!)
const Aws::DynamoDB::Model::PutItemOutcome result = dynamoClient.PutItem(req);
if (!result.IsSuccess())
{
std::cout << result.GetError().GetMessage() << std::endl;
return 1;
}
std::cout << "Done!" << std::endl;
//(途中省略...)
AWS CLI を使って、テーブルの内容を出力してみましょう。
aws dynamodb scan
コマンドにテーブル名を渡すと、以下のようにテーブルの内容を JSON で取得できます。
> aws dynamodb scan --table-name Game --endpoint-url http://localhost:8000
{
"Items": [
{
"State": {
"S": "off"
},
"Name": {
"S": "Switch"
}
}
],
"Count": 1,
"ScannedCount": 1,
"ConsumedCapacity": null
}
#おわりに
非常に長い道のりでしたが、DynamoDB local を C++ から操作することができました。AWS SDK for C++ は扱いやすく、DynamoDB を操作するための一通りのAPI が揃っています。これを導入すれば、C++ プログラマにとっては DynamoDB の敷居が一気に下がるのではないでしょうか。
DynamoDB local は 簡単にレコードを追加したり、削除したりできるので、プロトタイピングにもおススメですね。