昨日に引き続きTIG DX Unitの渋川です。
- Go Cloud#1 概要とBlobへの活用方法
- Go Cloud#2 Pub/Subの概要紹介
- Go Cloud#3 Go CloudのDocStoreを使う
- Go Cloud#4 URLを編集するパッケージ(この記事です)
- Go Cloud#5 AWSのローカルモック環境であるLocalStackを活用する
- Go Cloud#6 GCPのローカルエミュレータを活用する
- Go Cloud#7 PubSubドライバー(pubだけ)を実装してみる
これまで、基本的な機能を一通り紹介してきました。
Go Cloudでは何かとURL扱います。特にポータブルなAPIを使うと、mem://my-pub-sub
やら s3://my-bucket
やらで、URLでリソースの種類とその実態を指定しますし、場合によっては ?filename=collection.db
のようなクエリーで属性を設定したりします。
一方で、設定ファイルやらで正確なURLをすべてきちんと入れるのは大変です。
DocStoreでテーブルを10個使うアプリケーションがあり、データベース名までは同じだけど、コレクション名(≒RDBのテーブル)だけ置き換えたいみたいなケースでは、データベース名のところまでの1つだけを設定値として持ち、各テーブルのURLはプログラマブルに作りたいですよね? しかし、どこを書き換えればコレクション名が変わるかなど、細かいルールがバックエンドのドライバーごとに解釈が違うという難点があります。
ということでGo Cloud用のURL正規化パッケージを作りました。
このパッケージには、ちょっと省略形で書いたURLをGo Cloudで解釈できるURLに補完したり、一部書き換えたりといった関数が含まれています。なお、どの関数も、正規表現やテンプレートのパッケージと同じく、Must
が接頭辞についた関数も提供しております。
BlobのURLの正規化
NormalizeBlobURL(srcUrl string) (string, error)
がBlobのURLの正規化の関数です。コマンドラインツールでユーザーが入力するフォルダ名をfile://folder
形式にするといったちょっとした修正をします。Go Cloud、Cloudだけで使うのはもったいなので、CLIでも使おうと思って追加しました。リージョン名はAWS_REGION
という環境変数があればそこから補完します。
mem
→mem://
folder
→file://folder
s3://my-bucket
→s3://my-bucket?region=us-west-1
DocStoreの正規化
NormalizeDocStoreURL(srcUrl string, opt Option) (string, error)
という関数を提供しています。
DocStoreの場合、パスの階層構造やら主キーの設定の方法がバックエンドによって異なったりします。コレクション名は書き換えたいが、主キーはこのカラム名にしたい、みたいなのはこの関数を使えば一元化されます。
オプションは次の形式になっています。
type Option struct { |
例えば、memdocstoreバックエンドの場合は次のようなURLが生成されます。
goclodurls.NormalizeDocStoreURL("mem://", goclodurls.Option{ |
FireStoreの場合は、プロジェクト名/コレクションといった短い名前や、プロジェクト名/ドキュメント名/コレクション名といった短い名前を渡しても、Go Cloudが期待する名前(projectsやdatabasesやdocumentsというパスを挿入、データベース名のデフォルトは(default)
を利用する)に書き換えます。最初からvalidな本来のURLを入れることも可能です。
goclodurls.NormalizeDocStoreURL("firestore://my-project", goclodurls.Option{ |
DynamoDBはパーティションキーだけの場合はパーティションキーが主キーになり、パーティションキーとソートキーがあると複合主キーのようになるという特性があります。本ライブラリでは、PartitionKeyが空文字列なら前者のモード(KeyName=パーティションキー)に、PartitionKeyが入っていれば後者のモード(KeyName=ソートキー、PartitionKey=パーティションキー)になるようにしています。
goclodurls.NormalizeDocStoreURL("dynamodb://", goclodurls.Option{ |
goclodurls.NormalizeDocStoreURL("dynamodb://", goclodurls.Option{ |
PubSubの正規化
NormalizePubSubURL(srcUrl string) (string, error)
という関数を提供しています。これも今までのものとほぼ同じです。SNSはARNで書いても補完するし、SQSもhttpsのURLを書いても補完します。GCP PubSubはFirestoreと同様に固定のprojects/topicsを省略しても補完します。
gocloudurls.NormalizePubSubURL("arn:aws:sns:us-east-2:123456789012:mytopic") |
おまけ
type Person struct { |
このようなdocstoreをマッピングする構造体があったとすると次の関数で、テーブル定義のコマンドライン引数を生成します。
ds, err := gocloudurls.NewDynamoDBSchema(&Person{}, |
aws dynamodb create-table --table-name persons \ |
そのうち、Terraformのコードも生成したり、awscliを実行をしたり、というのも追加したいな、と思っています。
まとめ
最初のエントリーで紹介したように、クレデンシャルの問題以外を除けばマルチクラウドの利点を生かしたい場合はポータブル版のURLで扱うのがお手軽なことが多いです。しかし、特にDocStoreにおいて、URLのルールがバックエンドごとに違いすぎて、ポータブル版のAPIを扱うのが難しいというのを感じましたので、URLの操作もマルチクラウドにするためのユーティリティを実装しました。これでよりマルチクラウドが行いやすくなったと思います。