こんにちは。
システム開発部ネットワーク課のsupercontinueです。
swaggerとは?
- swaggerは定義したスキーマからAPIコードを生成してくれるジェネレータです。
- オープンソースです。
- go-swaggerは定義したスキーマからgo言語のサーバのコードを生成します。
弊社でも実際にリリースしたゲームで使いました。
もうずいぶん前になりますが、公式のgo-swaggerに機能追加したプルリクエストを送って、取り込まれた話をします。
何を追加したのか?
sessionData: type: object properties: sessionId: type: string deviceId: type: string uMain: $ref: '#/definitions/u_main'
- すると、下記のようなコードが生成されます。
type SessionData struct { DeviceID string SessionID string UMain *UMain }
プロパティの順番に注目してください。
- スキーマでは、sessionId、deviceId、uMain の順番になっています。
- ところが、go-swaggerでは、アルファベット順にプロパティを並べ替えてコードを生成します。
- 生成されたコードでは、DeviceID、SessionID、UMain の順番になっています。
順番が違うと何が困るのか?
そこで、プロパティの順番を明示的に指定する、
x-order
というカスタム属性を追加することにしました。- swaggerでは、
x-なんとか
という属性は、プラットフォームごとの独自拡張の属性として扱われています。 - たとえば、下記のようなカスタム属性があります。
x-go-name
: "string": give explicit type name to the generated modelx-nullable
: true|false (or equivalently x-is-nullable:true|false): accepts null values (i.e. rendered as a pointer)
- swaggerでは、
x-order
を定義したスキーマ。
sessionData: type: object properties: sessionId: x-order: 0 type: string deviceId: x-order: 1 type: string uMain: x-order: 2 $ref: '#/definitions/u_main'
- すると、下記のようなコードが生成されます。
- 構造体のプロパティの順番が
x-order
で指定した順番になります。
- 構造体のプロパティの順番が
type SessionData struct { SessionID string DeviceID string UMain *UMain }
実際に機能追加提案したコード
まずはレポジトリをForkします。
主要な変更は下記です。
// 変更前 func (g GenSchemaList) Less(i, j int) bool { return g[i].Name < g[j].Name }
// 変更後 func (g GenSchemaList) Less(i, j int) bool { a, ok := g[i].Extensions[xOrder].(float64) if ok { b, ok := g[j].Extensions[xOrder].(float64) if ok { return a < b } } return g[i].Name < g[j].Name }
変更点はわずかですが、「どこを変更すればいいのか?」を正確に把握するには、swaggerのコードを読み込む必要があります。
今回は、たまたま
Less
というメソッドが実装されていたので、変更が最小限ですみました。テスト用のコードの方が多いです。
実際のプルリクエストは下記です。
結構さくっとマージしてもらえました。
結果
公式のマニュアルにも
x-order
カスタム属性が記述されています。当時はさくっと採用されて嬉しかったです!
- オープンソースへの貢献は嬉しいものですが、負荷が高くなると辛くなるので。
独自レポジトリで改変して利用していると、公式が更新された場合、追っかけなくてはなりません。公式にマージしてもらうほうが楽です。
さっき見たら、下記のような2020年のissueがありました。(まだOpenしたまま)
- コードからYAMLへの逆変換したとき出力順についてですね・・・
- (機能には問題ないけど、)YAMLでも見た目を
x-order
の順番にしてほしいということだと思います。 - https://github.com/go-swagger/go-swagger/issues/2202
リベル・エンタテインメントでは、このような最新技術などの取り組みに興味のある方を募集しています。もしご興味を持たれましたら下記サイトにアクセスしてみてください。 https://liberent.co.jp/recruit/