go用のDynamoDBとDAXの合体クライアントを作った
ポケモンやってます!!!(未クリア) リングフィットやってません!!!!!!(リングコンで運動はしてる)
ラビフットかわゆす〜〜〜とか思ってたら、進化してエースバーンになったらリア充サッカー部員っぽくなって悲しいです。
(実はポケモンはルビサファ以来なんですけど、最近のポケモン、キモいデザインのやつ多くない?)
いつもどおり、表題まんまの話です。
とある事情からDynamoDBクライアントとDAXクライアントを合体させたクライアントを作りました。
実務で書いてたコードを仕事中にライブラリとして切り出したので、会社のリポジトリです。
名前は「ダイダックス」と読みます。スパロボ見たいでかっこいいでしょう??(急いでたから適当に命名した)
ケツにgoとついてるのは、Scala版を作る可能性があるためです。
どういうやつ?
DAXがサポートしてるAPIについてはDAXクライアントを使って実行し、非サポートAPIについてはDynamoDBクライアントを使って実行するというものです。
putItemとかgetItemはDAXクライアント、describeTableなんかはDynamoDBクライアントという感じ。
どういう用途で使うの?
DynamoDBクライアントのラッパーであるdynamoからDAXにアクセスするためです。
以下はdynamoのexampleからの抜粋です。
func main() { db := dynamo.New(session.New(), &aws.Config{Region: aws.String("us-west-2")}) table := db.Table("Widgets") // put item w := widget{UserID: 613, Time: time.Now(), Msg: "hello"} err := table.Put(w).Run() // get the same item var result widget err = table.Get("UserID", w.UserID). Range("Time", dynamo.Equal, w.Time). Filter("'Count' = ? AND $ = ?", w.Count, "Message", w.Msg). // placeholders in expressions One(&result) // get by index err = table.Get("Cateogry", "hoge"). Index("category-index"). One(&result) // get all items var results []widget err = table.Scan().All(&results) }
dynamoはdynamo.Newする以外にもaws-sdk-goのDynamoDBAPIからもインスタンスを作れるので、DynamoDBAPIを実装しているDAXクライアントをそのまま渡せるんですが、上記のExampleの頭のほうにもあるとおり、最初にdescribeTableを発行するAPIデザインになっているので、DAXクライアントからdynamoのインスタンスを作成して使おうとしても、dynamo.Tableを実行した時点でpanicを起こします。
(aws-dax-goのDAXクライアントは非サポートAPIを実行しようとするとpanicを起こすようになってます)
じゃあDAXクライアントがサポートしてないAPIの場合だけDynamoDBクライアントで実行する、DynamoDBAPIを実装したクライアントを作ればよくね?と思って作ったのが今回の合体クライアント。
以前のブログエントリでDAXクライアントがそのままdynamoで使えるとか書きましたが、
スマンなあれは嘘だ
どういう作り?
実装はファイル1つなので、直接みてくだせぇ
dydax-go/dydax.go at master · wano/dydax-go · GitHub
DynamoDBクライアントは構造体に埋め込んで、DAXクライアントは構造体のメンバとなっております。
DAXクライアントがサポートしてるAPIの場合は明示的にDAXクライアントを呼び出すように関数定義しておいて、残りのAPIについては構造体に埋め込んだDynamoDBクライアントのほうが勝手に呼ばれるようになっています。
動くの?
一応テストでどのクライアントが呼ばれるかは確認しているので、大丈夫の。。。はず。。。
感想
そもそもDockerでDAX-localを提供して欲しい。
DAXはVPC内からしかアクセスできないようになっていて、AWS環境にもっていったときに初めてDAXがdescribeTableなどをサポートしていないことに気づいた(ドキュメントちゃんと読めって話ですが)
というわけで、急ぎで今回のブツをこしらえたのです。