これはおそらく1つの正解がないベストプラクティスの質問です。私のハンドラのほとんどは、ハンドラに固有の作業を開始する前に、多くの一般的な初期化ジョブを実行する必要があるようです。例としては、ユーザーの認証、ロケールの検出、翻訳された文字列のロード、memcached値のチェックなどがあります。Goを使用して一般的なApp Engineハンドラタスクを達成する
これらのタスクの一部をinit
で処理するのが妥当と思われますが、ほとんどの場合、Http.Request
またはappengine.Context
が必要です。
ServeHTTP
を実装し、最後にカスタムのinit関数を実行する能力を追加します。私の知る限り見ることができるように、これは3つの選択肢を残します。問題は、自分で実装したGorillaマルチプレクサを使用することができないということですServeHTTP
。muxのフォークバージョンを使用してください(理想的ではありません)。
startHandler
関数を、アプリケーション全体のすべてのハンドラの先頭に置きます。面倒なようですが、普通のコードを隠すこととは対照的に、何が起ころうとしているのかは明らかです。ServeHTTP
すべてのハンドラに共通のジョブを処理するのに好ましい方法は何ですか?別の方法がないのですか?
ここでは、minikomiの回答で概説されているアプローチの完全なApp Engineの例を示します。また、Jeff Wendling's tutorialを訪れる価値があります。しばらくの間、私を投げた何
はpackage app
import (
"fmt"
"log"
"net/http"
"appengine"
"appengine/datastore"
"github.com/gorilla/context"
"github.com/gorilla/mux"
)
type Config struct {
DefaultLocale string
DefaultTimezone string
}
type ContextKey int
const (
SiteConfig ContextKey = iota
// ...
)
type InitHandler func(http.ResponseWriter, *http.Request, appengine.Context)
func (h InitHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// All handler initialisation tasks go here
c := appengine.NewContext(r)
k := datastore.NewKey(c, "Config", "site:config", 0, nil)
config := new(Config)
if err := datastore.Get(c, k, config); err != nil {
log.Fatal("Couldn't read config from datastore: %s\n", err.Error())
}
context.Set(r, SiteConfig, config)
// Finally, call the handler itself
h(w, r, c)
}
func init() {
r := mux.NewRouter()
r.Handle("/", InitHandler(home)) // Note: NOT r.HandleFunc!
http.Handle("/", r)
}
func home(w http.ResponseWriter, r *http.Request, c appengine.Context) {
site := context.Get(r, SiteConfig).(*Config)
fmt.Fprintf(w, "Locale: %s, timezone: %s.", site.DefaultLocale, site.DefaultTimezone)
}
router.Handle
なくrouter.HandleFunc
を使用する必要があります。データストア内の適切なエンティティと仮定すると、出力は次のようになります。
Locale: en_US, timezone: UTC.
私が最初に私が考えましたこの方法でゴリラmuxを使用することができなかった、その後、私はキャストに気づいた!ニース。このチュートリアルでは、さらにいくつかのサンプルコードを提供しています:http://shadynasty.biz/blog/2012/08/07/painless-web-handlers-in-go/最初の投稿をGAE固有の例で編集します。ありがとう:) –
素晴らしい!最初はあなたの心を包み込む(funcは機能を持っていますか?)しかし、それは非常に強力です!私はブログの投稿は私が最初にそれを学んだ場所だと思う。良いシリーズ。 – minikomi
2つのServeHTTPを効果的に直列に持つことができます。最初のマルチプレクサのもの、自分自身のものです。サンプルApp Engineアプリで質問が更新されました。 –