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?

More than 5 years have passed since last update.

GoogleAppEngine/Goで共通の値を保持したままAPI Handlerを実行する

Last updated at Posted at 2016-04-21

Context

今回は、contextを使って値を持ち回りながらHandler間で共有しようという話です。

Motivation

Wrapperで認証などの前処理を行ったあとに処理結果などをAPIに渡したい。
APIの引数にその度に渡す方法だと拡張性に乏しいので何かないか探していた。

実践

AppEngineのcontextを取得してから、これを親としたcontextを作成していきます。

wrapper_example
// 前後の処理は割愛します

type contextHandler func(ctx context.Context, w http.ResponseWriter, r *http.Request)

type Wrapper struct {
    handler contextHandler
}

func (w *Wrapper) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    // AppEngineのcontextを取得します
    ctx := appengine.NewContext(r)

    res, err := getHogehoge(foo, bar)
    if err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }

    // ここでresを保持するcontextを作成します
    newCtx := context.WithValue(ctx, "hoge", res)
    w.handler(newCtx, w, r)
}

contextの内部の値はinterface{]で保持されるため、reflectを使って取得していきます。

handler_example
func exampleHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
    // ここではhogeは単純に文字列を保持しているとします
    // structなどはまた違う取り出しかたが必要です
    hoge := reflect.ValueOf(ctx.Value("hoge")).String()

    do(hoge)
}

まとめ

このようにcontextを使用することでstructや変数を減らすことが出来るのでは、と思いました。
複数の値を保持する場合は、さらに重ねるようにしてcontextを作成します。
まだ使ったばかりなので、contextの生成コストを調べていないです。
使いながらパフォーマンスが気になったら、また新しいことを考えようと思います。
間違いの指摘などいつでもお願いします :thumbsup:

追記

https://code.google.com/p/googleappengine/issues/detail?id=12725
ここにある通り、golang.org/x/net/context/ctxhttp/cancelreq.goのbuildタグを削除しないと上手く動かないです。

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?