goa tips : v1.3 で追加された HashOf のバリデーションを使う

はじめに

goa のこと書くのずいぶん久しぶりになってしまいました. 仕事でも使ってて安定して動いていて,あんまり目新しいこともなくなってきて, API はこれで書くのが当たり前になりつつあり・・・.

まぁ,そんな言い訳はどうでもいいんですが, うかうかしているうちに v1.3 がリリースされました! 🙌

goa v1.3.0 · goa :: Design-first API Generation

v1.3 では,いくつか機能が追加されたんですが 密かに期待していた HashOf のバリデーションを設定する機能が追加されたのでこれを紹介しようと思います.

HashOf の機能

HashOf は key と value からハッシュマップをつくる DSL です.

使い方とかはこの辺を参照してください http://ikawaha.hateblo.jp/?page=1473951553

たとえばワインを評価するようなデータが,ワインの銘柄と5段階評価のペアの集合で受け渡されるとしたときに, goa だったら,こんな感じのエンドポイントが用意できます.

Action("updateRatings", func() {
    Payload(func() {
        Member("ratings", HashOf(String, Integer))  // ← ワインの銘柄(文字列)と評価(数字)のペアみたいなのを受け取りたい
})

いままでは,これはデータを受けとった後,コントローラーで入っている銘柄や評価をバリデーションしてました. たとえば,評価が,1〜5 に収まってるかどうか,とか.

でも,これって goa っぽくないですよね :p

v1.3 では,このバリデーションをデザインに書けるようになりました.

Action("updateRatings", func() {
    Payload(func() {
        Member("ratings", HashOf(String, Integer,
            func() { Pattern("[a-zA-Z]+") },  // key のバリデーション
            func() { Enum(1, 2, 3, 4, 5) },    // value のバリデーション
    ))
})

めっちゃスッキリです.

この機能,実は v1.2 の時点で既に ArrayOf に似たような機能が実装されてて,ArrayOf の要素はバリデーション出来るようになってました.HashOf についても同様に出来るようなことがドキュメントに書かれてて,これは使える!とウキウキしてたんですが,実際使ってみると,バリデーションは受けとるんだけど,生成されるコードにバリデーションする部分のコードがなかったのでした orz

そんなわけで,この機能の中身は自分で pr しました.なんとも OSS っぽい体験.

開発もだいぶ落ち着いてる感じのある goa ですが,v2 の開発がかなり進んで,もうだいぶ形になってるみたいです. v2 では gRPC にも対応してくとのことなので,今からリリースが楽しみですねー.