自分は元々IoTボタンを使って勤怠を付けていたのだけれど、Goの練習がしたかったのでRubyコードをGoでリライトした。ちなみにコード量は(ボイラープレート的記述によって)増えた。とはいえ分かりやすさはほぼ変わっていないし、型がつく安心感がある。
うちはAKASHIという勤怠管理システムが使われていて、APIを使って勤怠をつけることができる。
せっかく書いたので公開した。各トークンなどは環境変数から取るようにしたので、他の人でも使えるようになっている。
とはいえIoTボタンの設定はまあまあ面倒だったので、何も考えず脳ポイで勤怠つけられるようになるかというと微妙で、一定の努力が必要。
感想
Lambda
これまではオンラインエディタでRubyをいじるという生活だったけれど、Goになったのでバイナリをアップロードしなければならなくなり、オンラインエディットはできなくなった。GitHub Actionsから良い感じにLambdaのデプロイをやりたいけれど、SAMやCDKといったちょっと派手な手段を使わないといけなそうなのが地味に面倒だなと感じる。
パラメータまわり
まずLambdaに渡ってくるパラメータの形式はどうやってGoにコードするんだろうと思っていたけれど、とにかくmap[string]interface{}
で無理矢理ハンドルできるということが分かった。取り出すときは、これまたclick_type := event.(map[string]interface{})["deviceEvent"].(map[string]interface{})["buttonClicked"].(map[string]interface{})["clickType"].(string)
のように記述していて豪快。几帳面な人はちゃんとstructにしたほうがいいと思うけど、structで受けるときって不要なパラメータもコードしないといけないのかな?
func HandleRequest(ctx context.Context, event interface{}) (map[string]interface{}, error) { // こんな感じで取れる click_type := event.(map[string]interface{})["deviceEvent"].(map[string]interface{})["buttonClicked"].(map[string]interface{})["clickType"].(string) }
ハンドラまわり
次にLambdaでGoを動かすときはハンドラ名どう設定するのだろうと思っていたけれど、Rubyではファイル名.ハンドラメソッド
のように記述していたところ、Goではexecutable_file_name
だけで済むようになっていた。今回はmain
としてビルドしてあるので、main
と指定すれば済んだ。
ほか
*string
が返ってきたのをそのままPrintln
しようとしてアドレスが表示されてしまうといった凡ミスがあった。non-nilならdereferenceして表示、という処理に置換した。たぶんGo入門者あるあるだと思う。
入力に関してはTabnineの強力なサポートを得られたのであまり困らなかった。ボイラープレート的な処理が多いのでそのへんはAI任せでいいと思う。実際、クエリパラメータのmap2つをmergeするといった処理は、「これfor-loopだな〜どう書くんだっけ」と思いながら書いてると、すぐrange
を使った書き方を提案してくれたので、それで済んだ。体験が良い。
ビルドも早かったけど、go modまわりの知見がなかったので、ライブラリ落としてくるのが結構大変だった。このへんはなんか不親切だと思うけど慣れだと思う。
本
これ読んで軽く復習しながらやりました。