GoaでGenMazeサーバーを書いた

迷路生成サーバーを作った。実装はgithubに置いた。 gRPCやOpenAPIのサーバーにする必要は全くなかったけどGoaの勉強のためにサーバーにした。 気が向いたらSVG生成するgRPCクライアントを書くつもり。

GenMaze GenMaze

使ってみた感想

goa はGo構文を利用してOpenAPI,gRPCコードを生成するDSLを提供してくれる。 DSLに慣れたら簡単にAPIを実装できるしgRPC,OpenAPIの同時対応などもできていい。 plugin 機構がありi18nにも対応できそうなので(試してないけど)APIドキュメントの面で期待ができる。 またGo構文を使っているのでエディタでハイライトされたりするのが嬉しい。

一方で、DSLをGoの構文で代替しているので func(){} を使ったりと文法が実装に振り回されてしまってる。 構文こそGoだけど意味は違うので書いていて違和感が伴う。とくにエディッタでの編集中に型検査などの恩恵を受けられない。

言語内DSLを自然に定義できるOCamlなどの言語が便利に感じるだろうなぁと思った。

振り返り

  • Goaの資料
  • Goaの概要

Goaの資料

公式の情報

関連公式資料

使ってる人の紹介記事

Goaの概要

使い方

1
2
3
4
5
6
7
$ cd $proj_top
$ mkdir -p ./design
$ touch ./design/design.go
# コード生成 
$ goa gen $(basename $proj_top)/design
# 利用コード生成
$ goa example $(basename $proj_top)/design

swagger-uiを落としてくる

UIに備わってるクライアントは最初に設定されてるURLスキーマを使う。 なので openapi.json の説明するAPIが HTTP のみサポートしてるときに公式のUIに手を加えずに使うとHTTPSを利用することになる。 なのでドキュメント上でのデモは失敗する。

1
2
3
4
wget https://github.com/swagger-api/swagger-ui/archive/v3.25.4.tar.gz
tar xvfz ./v3.25.4.tar.gz
mv ./cmd/calc/swagger-ui-3.25.4/dist/ ./public/swagger-ui/
sed -E s/url: "https?:\/\/.*",$/url: "http:\/\/localhost:8088\/hoge.json"/g ../../public/swagger-ui/dist/index.html ```

gRPC

はじめに design/design.go からコード生成した時は GRPC 対応に失敗した。 とりあえず置いておいたのだけど、理由は rpc:tag がないからって出てくる。 gRPCが利用するプロトコルバッファでのシリアライズでは事前にフィールドのシリアライズ順序が必要で指定してないとならない。

Type/ResultTypeField がインデックスを持てるのでちゃんと型を使う必要がある。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// Before
Result(func() {
  Attribute("field", String)
  Attribute("start", Position)
  // ...
})
// After
Result(ResultType("generated_maze", func() {
  Attributes(func() {
    Field(1, "field", String)
    Field(2, "start", Position)
    // ...
  })
})

ref. https://godoc.org/goa.design/goa/dsl#Field

comments powered by Disqus