2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

openapi-generator-cli を使って生成したコードを使ってリクエストとレスポンスに使う

Posted at

openapi-generator-cli とは?

openapi-generator-cliは、OpenAPIで書かれた仕様書からコードを生成するものです。

特にGo言語用というわけではなく、WebApplicationFrameworkに従ったコードも生成してくれます。どんな言語、Frameworkに対応しているかは、READMEのOverviewを見てみると良いでしょう。Perlもありますね(ないと思ってた)。

今回、WebApplicationFrameworkにFiberを使ったのですが、残念ながら、Fiberには対応していません。ですが、生成したコードを使うことは出来ます。

openapi-cli-generatorを動かす

今回は、Dockerで動かしました。openapi-generator-cliのオプションとしては、generateから後ろですが、オプションが多いですね。

docker run --rm -u "${UID}:${GID}" -v "${PWD}:/local"  \
	    openapitools/openapi-generator-cli generate -g go \
		--skip-validate-spec \
		--global-property models,supportingFiles,modelDocs \
		--additional-properties withGoMod=false \
		--package-name package名 \
		-i /local/docs/openapi/openapi.json \
		-o /local/internal/interfaces/api/generated/package名/

一つずつ見ていきましょう。

  • generate ... コードを生成する。そのままです。以下は generateのオプションです
  • -g go ... Go用のコードを生成する
  • --skip-validate-spec ... 仕様書の書式のチェックをスキップ
  • --global-property models,supportingFiles,modelDocs ... models,supportingFiles,modelDocsを生成する
  • --additional-properties withGoMod=false ... go.mod を作らない
  • --package-name package名 ... package名を指定する
  • -i /local/docs/openapi/openapi.json ... 仕様書を指定する
  • -o /local/internal/interfaces/api/generated/package名/ ... 出力先の指定(/localに、current directoryをmountしています)

--global-property を指定しないと、生成したコードをそのまま使えませんでした。今回使用する用途的に必要そうな最低限の組み合わせになります(modelDocsは別に不要ですが)。

生成されたコードを使う

openapi-generator-cliが生成するのは、主に、

  • client.go ... APIを叩くためのコード
  • configuration.go ... エンドポイントのURL等の設定っぽい
  • model_*パス_request.go ... 各APIのリクエストに関する型や実装
  • model_*パス_response.go ... 各APIのレスポンスに関する型や実装

GET

で使え...ません。GETのAPIに関しては、model_*パス*request.goが存在しないので、fiberのQueryParserに渡せません。

--global-propertyapis を渡せば、api_*.goにGETようの型は作ってくれるのですが、構造体のメンバがprivateなので、FiberのQueryParserに渡すことができません。残念。

コードを参考にして、構造体を作れば楽なのは楽かもしれません。

POST

model_*パス*request.goの中にJSON用の構造体が入っていますので、それが使えます。例えば、こんな感じですね。

type YourApiRequest struct {
	UserID string `json:"user_id"`
}

fiberBodyParserにそのまま渡すことが出来ます。

  c.BodyParser(req)

レスポンス

model_*パス*response.goの中にJSON用の構造体が入っていますので、それが使えます。例えば、こんな感じですね。

type YourApiNameGet200Response struct {
	Result []YourApiNameGet200ResponseResultInner `json:"result"`
}

この型通りにデータを作ってやって、JSONにすれば、そのままレスポンスに使えます。

  data := YourApiNameGet200ResponseResultInner{
   // 略
  }
  c.JSON(your_pacakge.NewYourApiResponse(data))

各POSTの型にダミーのメソッドを作る

codegen/openapi-request-generator.sh というプログラムで、CanWrapというメソッドを各作ります。やってることは、以下のように超単純です。

#!/bin/bash

dirs=$1

if [ "$dirs" = "" ]; then
  dirs="your_pacakge_name"
fi

for dir in $dirs; do
  echo -e "package $dir\n" > internal/interfaces/api/generated/$dir/generated_func.go;
  grep 'Request struct' -r internal/interfaces/api/generated/$dir | grep type |cut -d ' ' -f 2 | sort | xargs -I {} echo "func (*{}) CanWrap() { }" >> internal/interfaces/api/generated/$dir/generated_func.go
  go fmt internal/interfaces/api/generated/$dir/generated_func.go
done

各Postリクエストの型に対して、CanWrapという何もしないメソッドを定義しています。CanWrap()は、RequestWrapper interfaceを満たすためのメソッドです。

type RequestWrapper interface {
        CanWrap()
}

これで何が嬉しいかと言うと...前回書いたやつが、できるようになりますね。

以下、略。

終わり

以上、openapi-generator-cli を使えば、楽できますよという話でした。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?