.NET 用の Amazon QLDB ドライバーを使ってみた

2022.08.02

いわさです。

Amazon QLDB では改ざん防止の性質をもつ台帳データベースです。
これまで何度か記事で利用方法を紹介してきましたが、コンソールのクエリエディタを使うことが多かったです。

今回、.NET アプリケーションで台帳データベースを扱う機会がありましたので方法をご紹介します。

.NET 用 Amazon QLDB ドライバーを使う

Amazon QLDB を操作するクライアントのために、各ランタイム向けにオープンソースの QLDB 用ドライバーが用意されており、こちらを利用することが推奨されています。

言語としては Java, .NET, Go, Node.js, Python 向けに提供されています。
本日はこの中の .NET 用ドライバーを使用します。

インストール

NuGet パッケージで提供されているので導入自体は非常に簡単です。

今回は .NET 6 にてコンソールアプリケーションを作成し、そちらに組み込みを行ってみたいと思います。

% dotnet new console
テンプレート "コンソール アプリ" が正常に作成されました。

作成後の操作を処理しています...
/Users/iwasa.takahito/work/hoge0802qldb/hoge0802qldb.csproj で ' dotnet restore ' を実行しています...
  Determining projects to restore...
  Restored /Users/iwasa.takahito/work/hoge0802qldb/hoge0802qldb.csproj (in 88 ms).
正常に復元されました。

% dotnet add package Amazon.QLDB.Driver
  Determining projects to restore...
  Writing /var/folders/4d/nhd1bp3d161crsn900wjrprm0000gp/T/tmphF4yi3.tmp
info : Adding PackageReference for package 'Amazon.QLDB.Driver' into project '/Users/iwasa.takahito/work/hoge0802qldb/hoge0802qldb.csproj'.
info :   GET https://api.nuget.org/v3/registration5-gz-semver2/amazon.qldb.driver/index.json
info :   OK https://api.nuget.org/v3/registration5-gz-semver2/amazon.qldb.driver/index.json 647ms
info : Restoring packages for /Users/iwasa.takahito/work/hoge0802qldb/hoge0802qldb.csproj...
info :   GET https://api.nuget.org/v3-flatcontainer/amazon.qldb.driver/index.json

:

以上で導入は終わりです。
Amazon QLDB では、通常 Ion データ形式が利用されていますが、.NET インスタンスへシリアライズするためのライブラリも別途提供されています。
こちらは機会があればまたご紹介出来ればと思いますが、特殊な事情がない限りは原則併用すべきでしょう。
生の Ion をそのまま使うのは実装コストつらい印象があります。

データの取得

ここでは以下のようにいくつかのサンプルデータが存在する場合を前提に、データの取得をまず行ってみます。

使い方としては、QLDB ドライバーを初期化し、トランザクションに対して操作を行います。
同期と非同期それぞれのメソッドが用意されていますので設計にあわせて選択が可能です。
ここではコンソールアプリなので同期でも良かったのですが、利用したい環境が Web アプリケーションだったので、非同期メソッドを選択していますのでご注意ください。

Program.cs

using Amazon.QLDB.Driver;

var qldb = AsyncQldbDriver.Builder().WithLedger("hoge-ledger").Build();
var result = await qldb.Execute(async txn => 
{
    return await txn.Execute("SELECT * FROM Person");
});
await foreach(var row in result)
{
    System.Console.WriteLine(row.GetField("FirstName").StringValue);
}
% dotnet run
Raul
Alexis
Salvatore
Brent
MelVIN

トランザクションへのExecuteでクエリを発行しています。
少し特有の癖はありますが、複雑なことはやっていないことがわかると思います。

テーブルとデータの作成

では、次は応用です。
先程は既存テーブルからのデータ取得でしたが、今度は新規テーブルを作成し、そこへデータを数件登録してみましょう。

Program.cs

using Amazon.IonDotnet.Tree.Impl;
using Amazon.QLDB.Driver;

var qldb = AsyncQldbDriver.Builder().WithLedger("hoge-ledger").Build();
var result = await qldb.Execute(async txn => 
{
    //Create Table
    await txn.Execute("CREATE TABLE Hoge");

    //Insert
    var valueFactory = new ValueFactory();
    var ionHoge1 = valueFactory.NewEmptyStruct();
    ionHoge1.SetField("Prop1", valueFactory.NewString("Hoge1"));
    ionHoge1.SetField("Prop2", valueFactory.NewInt(111));
    var ionHoge2 = valueFactory.NewEmptyStruct();
    ionHoge2.SetField("Prop1", valueFactory.NewString("Hoge2"));
    ionHoge2.SetField("Prop2", valueFactory.NewInt(222));
    await txn.Execute("INSERT INTO Hoge ?", ionHoge1);
    await txn.Execute("INSERT INTO Hoge ?", ionHoge2);

    //Select
    return await txn.Execute("SELECT * FROM Hoge");
});
await foreach(var row in result)
{
    System.Console.WriteLine(row.GetField("Prop1").StringValue + ":" + row.GetField("Prop2").IntValue.ToString());
}

考え方は同じでCREATE TABLEINSERTもトランザクションインスタンスへ操作するだけです。
ひとつ注意点としては、Ion データを準備する兼ね合いでAmazon.IonDotnet.Tree.Impl.ValueFactoryで作成データを生成しています。

% dotnet run
Hoge1:111
Hoge2:222

実行してみると上記のように新規データを取得することが出来ました。
念の為コンソールのクエリエディタでも参照してみます。

うまく登録されていました。

さいごに

本日は、.NET 用の Amazon QLDB ドライバーの使い方をご紹介しました。

かなりシンプルに利用出来ると思いますが、トランザクションに対してクエリを発行し、取得したオブジェクトに対してフィールド名を取得して値を取得する様子は一昔前のデータアクセス処理っぽい感じがしますね。
EntityFramework や Dapper に慣れていると少し低レイヤーな感じがするかもしれませんが、生で AWS API を呼び出すよりは断然実装が楽になりそうですね。