[golang]Interfaceのオススメの使い方4 ~DB切り替え~

こんにちは。KOUKIです。

今日は、Interfaceの使い所の一つである「DBの切り替え」について記事にしました。

アプリケーションを実装していく中で、開発中はDynamoDBを使っていたのに、本番ではRedisを使うことになっちゃった!といった経験はありませんか?

そんな時に使えるテクニックです。

進め方

DBの切り替えと書きましたが、今回はDynamoDBとsyncパッケージのMapを使ったDemoアプリケーションを作成します。Mapは別にデータベースじゃないじゃん!?と思うかもしれませんが、MySQLでもPostgreSQLでも問題なく動きますので、ご心配なく。

実装としては、最初にDynamoDBの接続処理を書き、次にsync.Mapを使ったローカルキャッシュを作成します。そして最後に、Interfaceを使ってDBの切り替え処理を実装する流れです。

環境

Dockerとdocker-composeを使いますが、かなり便利なツールです。この機会に使ってみてはいかがでしょうか。

Workspace

最初にワークスペースを用意しましょう。

dataディレクトリには、dynamodbのデータが入ります

事前準備

たくさんのファイルが必要ですが、コピペでOKです。

Dockerfile

Dockerfileには、Go言語の実行環境を定義します。

github.com/cespare/reflex」は、ソースコードのビルドを自動的に行ってくれる便利ツールです。これを導入することでDockerコンテナを立ち上げ直さなくとも、ファイルを保存するだけでソースコードの変更を反映させることが可能です。

ただし、Windowsだと動かないかもしれません。

docker-compose.yml

ここには、GoとDynamoDBのコンテナ情報を記載します。

main.go

main.goには、net/httpパッケージを使った簡易サーバーを実装します。

コンテナの立ち上げ

以下のコマンドで、コンテナを立ち上げましょう。

動作確認

コンテナが立ち上がったら、「localhost」にブラウザからアクセスしてください。

上の画像のように表示されていればOKです。

DynamoDBの実装

では、DynamoDBの接続処理を実装していきましょう。

DynamoDBの使い方については、以下を参考にしてください。

まずは、必要なデータ型を定義します。

「dynamo」キーは、DynamoDBのデータとして扱えるようにするもので必須です。また、定義したデータ型の中に「hash」がないとDynamoテーブルを作成するときにエラーになるので注意しましょう。

接続処理は、以下のような感じで書きました。

次は、main関数からこの処理を呼びます。

このアプリは、以下のリクエストを送ることで動作します。

POST: http://localhost?name=test&text=test2
GET: http://localhost?name=test

ローカルキャッシュの実装

sync.Mapを使って、ローカルキャッシュを作成します。これは、DynamoDBと切り替えができるようにするためのもので、他のDBでも構いません。

ローカルキャッシュについては、こちらを参考にしてください。

まずは、データ格納処理です。

Interfaceを使ったDB切り替え

いよいよ、Interfaceを使ってDB切り替え処理を実装します。

やりたいことは、先ほど作成したDynamoDBとローカルキャッシュをisMock変数に格納される値によって切り替えることです。

パラメータやコンフィグ情報によってDBを切り替えられたら便利ですよね。

DomainにInterfaceを定義

最初にDomainにInterfaceを定義します。

Interfaceに設定するメソッドは、DynamoDBとローカルキャッシュに設定したメソッドと同じセマフォでなければなりません。これがです。

Interfaceの反映

repository/dynamodb.goを以下のように修正します。

NewDynamoDBRepoの戻り値をInterfaceにしました。

また、mockのNewMockDynamoDBRepoに関しても戻り値をInterfaceにします

Go言語では、Interfaceに定義したメソッドを実装していれば、暗黙的に実装したことにしてくれます。「mockDynamoDBRepo」も「dynamoDBRepo」もどちらもStoreとGetByNameメソッドを定義しているので、インターフェース要件を満たし、戻り値として返すことができるのです。

切り替え処理

main関数に切り替え処理を追加しましょう。

mock.jsonに以下の記述を書いてください。

これは、Mockモードにするか否かの設定値です。

main関数を修正します。

これでOKです。dr変数には、domainに定義したDynamoDBRepo Interfaceを指定しました。これで、isMockの値によってNewMockDynamoDBRepoかdynamoDBRepoのどちらかを取得できます。

これにより、それぞれのデータに紐づいたメソッドが呼ばれるので、DBの切り替え処理が実現できるという仕組みです。

動作確認

動作確認をしてみましょう。

Mockモード

以下のURLにリクエストを送ってみましょう。

POST: http://localhost?name=mock&text=This is a MockMode
GET: http://localhost?name=mock

ローカルキャッシュからデータの格納/取得ができたようですね。

DynamoDBモード

is_mockの設定をfalseにします。

コンテナを立ち上げ直します。

POST: http://localhost?name=dynamodb&text=This is a dynamodb
GET: http://localhost?name=dynamodb

OKですね。うまく切り替えられたようです。

一応、DynamoDBのデータも確認してみましょう。「localhost:8000/shell」にアクセスしてください。

Mockのデータが確認できないので、切り替え処理には問題がないようですね。

おわりに

いかがだったでしょうか。

Interfaceを使えばこんなことも実装可能です。参考になれば嬉しいですね。

それでは、また!

ソースコード

main.go

domain/dynamodb.go

repository/mock/dynamodb.go

repository/dynamodb.go

Go記事まとめ

関連記事

コメントを残す