Goa 更新情報 v3.9.0
概要
Goa の更新情報メモです。今回のバージョンアップは細かな修正ですが BREAKING CHANGE を含みます。
Goa v3.9.0
主な変更内容
- エラーフォーマッターが context を取るようになりました(BREAKING CHANGE)#3137
- Goa のエラー構造体のメソッドに
ErrorName()
がありますが、こちらは非推奨となり、GoaErrorName()
が新しく導入されました #3105 - OpenAPI ドキュメントに要素を強制的に反映させる
Meta(type:generate:force)
が v3.8.5 で導入されましたが、指定しても出力されないケースがありこれが修正されました
詳細
エラーフォーマッターが context を取るようになった件
これは破壊的変更になります。具体的には HTTP トランスポートの話になります。
エラーフォーマッターが必要になるのは、エラーのうちでも特にサービスメソッドに到達する前の処理で HTTP トランスポートで発生してしまったエラー(バリデーションなど Goa が生成したコード内で生まれるエラー)をカスタマイズするケースです。
たとえば、入力時のバリデーションで Bad Request が発生した場合や、なんらかのエラーが発生して起こる Internal Server Error に対してエラーの形式を制御します。
この機能が導入された議論の詳細は issue を参照ください。
で、これが、これまでは
// NewErrorResponse creates a HTTP response from the given error.
func NewErrorResponse(err error) Statuser {
if gerr, ok := err.(*goa.ServiceError); ok {
return &ErrorResponse{
Name: gerr.Name,
ID: gerr.ID,
Message: gerr.Message,
Timeout: gerr.Timeout,
Temporary: gerr.Temporary,
Fault: gerr.Fault,
}
}
return NewErrorResponse(goa.Fault(err.Error()))
}
という形式だったのが、この変更で以下のように第一引数に context を取るようになりました。
// NewErrorResponse creates a HTTP response from the given error.
func NewErrorResponse(ctx context.Context, err error) Statuser {
if gerr, ok := err.(*goa.ServiceError); ok {
return &ErrorResponse{
Name: gerr.Name,
ID: gerr.ID,
Message: gerr.Message,
Timeout: gerr.Timeout,
Temporary: gerr.Temporary,
Fault: gerr.Fault,
}
}
return NewErrorResponse(ctx, goa.Fault(err.Error()))
}
context、そりゃ合った方がいいけど、なくてもいいんじゃないかな・・・という気もしますが Clue の context logger とか使っていたらやはりここに context 欲しいよな、という気もします。
GoaErrorName()
が新しく導入された件
Goa のエラー構造体が持つ、ErrorName()
が非推奨になった理由は、他のモジュールとかで ErrorName()
を実装した ErrorNamer なエラーが存在すると、Goa のエラーかどうかをこれを目印に判定できないから、という理由です。
Goa では ErrorNamer というインターフェースが用意されています(今回非推奨になりましたが継続して利用は可能です)。
type ErrorNamer interface {
ErrorName() string
}
具体的には次のようなコードが問題になります。
if _, ok := err.(goa.ErrorNamer); !ok {
report(error)
}
なぜなら、ErrorName()
を実装してしまうエラー構造体があるかも知れないからです。そこで今回、名前がバッティングしないように GoaErrorNamer
が用意されました。
type GoaErrorNamer interface {
GoaErrorName() string
}
今後はこちらをご利用してください。ということでした。
破壊的な変更が入りましたが、機能として大きく変わるものはありませんでしたね。
Happy hacking!
Discussion