구글 AppEngine/Go에서 공통 값을 유지하면서 API Handler 실행

5421 단어 Go

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의 생성 원가를 조사하지 않았습니다.
만약 사용하면서 연기에 신경을 쓴다면, 나는 다시 새로운 일을 고려하고 싶다.
언제든지 오류 표시

추기


https://code.google.com/p/googleappengine/issues/detail?id=12725
여기서 보듯이 golang.org/x/net/context/ctxhttp/cancelreq.go의build 라벨을 삭제하지 않으면 순조롭게 작동할 수 없습니다.

좋은 웹페이지 즐겨찾기