GolangのRedashクライアントライブラリはいくつかあるものの、メンテナンスが活発でなかったり、一部のリソースしか操作できなかったりするため、新しくライブラリを書いた。
※その他のライブラリ
- https://github.com/koooge/redash-sdk-go
- https://github.com/ynishi/redash
- https://github.com/snowplow-devops/redash-client-go
- https://github.com/RecoLabs/redash-go-sdk/
RedashのAPIは一応、ドキュメントがあるもの網羅的ではなく、リファレンスとしてはほとんど使えないので、Redashのソースコードとredash-toolbeltを参考にした。
SPAなのですべての操作はAPIで行われているが、外部公開を考慮していないものもいくつかあるようで、正しくないパラメータを送るとすぐにInternal Server Errorになってしまったり、同じAPIが構造の異なるスキーマを返したりと癖があり、少し時間がたつとすぐに腐ってしまいそうなので、このライブラリではそれなりに頑張ってテストを書いている。ユニットテストだけでなく、DockerでRedashを立ち上げてのインテグレーションテストも一通り書いた。
使い方
以下はクエリを作成して、実行結果を表示する例。
package main import ( "context" "fmt" "time" "github.com/winebarrel/redash-go" ) func main() { client, _ := redash.NewClient("https://redash.example.com", "<secret>") //client.Debug = true ctx := context.Background() query, _ := client.CreateQuery(ctx, &redash.CreateQueryInput{ DataSourceID: 1, Name: "my-query1", Query: "select 1", }) var buf bytes.Buffer job, _ := client.ExecQueryJSON(ctx, query.ID, &buf) if job != nil { for { job, _ := client.GetJob(ctx, job.Job.ID) if job.Job.Status >= 3 { buf = bytes.Buffer{} client.GetQueryResultsJSON(ctx, query.ID, &buf) break } time.Sleep(1 * time.Second) } } fmt.Println(buf.String()) }
REST APIをマップしているので ListAlerts()
でアラートの一覧を表示したり、CreateDashboard()
でダッシュボードを作ったり…とリファレンスを見れば大体の操作はわかると思う。
クエリの実行、Jobまわりは癖があるのでAPIそのままではないが、普通に使える気はする。 Job一覧を表示するAPIは未だ見つけられず。
デバッグとppcat
APIの調査のため、ローカルでRedashを立ち上げてひたすらたたいたいた。 redash-goにデバッグフラグを追加して、HTTPのリクエストとレスポンスをダンプし、流れてくるJSONを観察。
https://github.com/winebarrel/redash-go/blob/main/client.go#L115-L118
if client.Debug { b, _ := httputil.DumpRequest(req, true) fmt.Fprintf(os.Stderr, "---request begin---\n%s\n---request end---\n", b) }
そのJSONをJSON-to-Go: Convert JSON to Go instantlyでGolangの構造体に変換する、ということを繰り返していたが、レスポンスの一行JSONが見にくく、それをいちいちコピペで整形する手間がめんどくさかったのでppcatというツールも作った。
これはテキストにJSONっぽい行が含まれていたらパースしてみてJSONだったら整形して表示するというもの。 たとえば上の出力をppcatに通すと以下のようになる。
大分見やすくなったので開発も捗った。
それはさておき