goa のリクエストコンテキスト
概要
リクエストコンテキストは、goa のすべてのコントローラーのアクションメソッドに第1のパラメータとして提供されるデータ構造です。 これは、生成された構造体に context.Context インターフェースをラップすることで、インタフェース境界を越えてコンテキストを渡すという Go チームが行った仕事を活用しています。
goaは、コード生成を活用して、“型付き"メソッドを使用してリクエスト状態にアクセスを提供する アクション固有の フィールドを定義します。
たとえば、ID
というパス・パラメータがデザインで Integer
型として定義されている場合、対応するコントローラのアクションメソッドは int
型の ID
という名前のフィールドを公開するコンテキストデータ構造を受け取ります。
リクエスト・ペイロードについても同様であるため、アクションコンテキストのPayload
フィールドにアクセスすると、デザインに記述されているアクションに固有のデータ構造が返されます。
これにより、リフレクションやコンテキストを構造体に"バインド"する必要性が緩和されます。
これは、レスポンスを書く場合にも当てはまります。基本的な http ResponseWriter がレスポンスを書くために利用可能である一方、アクションコンテキストは、デザインに記述されたレスポンスを記述するためのアクション固有のメソッドも提供します。 これらの生成されたメソッドは、たとえば、正しいステータスコードと content-type ヘッダーを記述します。 また、デザインに記述されているメディアタイプから生成されたカスタムデータ構造を使用してレスポンスボディを指定することもできます。
コンテキスト関数
goaパッケージは、リクエストコンテキストに格納されたデータを抽出するために使用できる一連の関数を公開します。
それらはすべて Context
をプレフィックスとする関数です。
たとえば ContextResponse は指定されたコンテキストからレスポンスデータを抽出します。
これらの関数は、生成されたデータ構造にアクセスするのではなく、ミドルウエアのような生の context.Context
の値にアクセスするコードとして有用です。
goa パッケージは、With
をプレフィックスとする関数を公開し、コンテキストを受け入れ、関数に提供された追加データを埋め込んだ新しいコンテキストを返します。例えば、WithLoggerはコンテキストにロガーを設定して返します。
Deadline の設定
前述したように、各コントローラのアクションコンテキストは golang パッケージの context をラップしています。 これは、Deadline とキャンセル信号がすべてのアクション実装で利用可能であることを意味します。 組み込みの Timeout ミドルウェアは、サービスまたはコントローラがすべてのリクエストに対してタイムアウト値を定義できるようにするこの機能を利用しています。