import "github.com/guregu/kami"
か、 import "gopkg.in/guregu/kami.v2"
KAMI(神)は、リクエストコンテキストのコンテキストとルーティングにHTTPTREEMUXを使用した小さなWebフレームワークです。ログとパニックフックに加えて、リクエストの前後に階層ミドルウェアを実行するためのシンプルなシステムが含まれています。 Einhorn経由の優雅な再起動もサポートされています。
Kamiは、ルート、ミドルウェア、およびコンテキスト「God Object」の中央登録ポイントとして使用するように設計されています。グローバル関数を使用することをお勧めしますが、Kamiはkami.New()
で複数のMuxesをサポートしています。
どこにでもkami.Handler()
自由にマウントできますが、役立つkami.Serve()
関数が提供されます。
ここにカミの誕生に関するプレゼンテーションがあり、いくつかのデザインの選択肢を説明しています。
context
とx/net/context
両方がサポートされています。
KamiとContextを使用した不自然な例で、挨拶をローカライズします。
スキップ⏩
// WebServerPackage Mainimport( "fmt" "net/http" "" context "" github.com/guregu/kami "" github.com/my-github/greeting "コンテキスト、w http.responsewriter、r *http.request){hello:= Greeting.FromContext(ctx)name:= kami.param(ctx、 "name")fmt.fprintf(w、 "%s、%s!"、hello、name) } func main(){ctx:= context.background()ctx = greeting.withcontext(ctx、 "hello")//デフォルトGreetingkami.context = ctx //すべてのリクエストスカミの基本コンテキストを設定します。 .use( "/hello/"、greed.guess)//このミドルウェアを使用してパスの下に使用します/hello/kami.get( "/hello/:Name "、Greet)// urlkami.serve()にパラメーターを持つハンドラーを追加
//パッケージグリーティングストアコンテキストのグリーティング設定。パッケージGreetingimport( "net/http" "context" "golang.org/x/text/language")//コンテキストの詳細とこれを行う理由については、 https://blog.golang.org/contexttype ctxkey intvarキーctxkey = 0var greetings = Map [Language.tag] String {Language.AmericanEnglish: "yo"、language.panese: "こんにちは"、 } //推測は、受け入れ言語とセットを調べるKAMIミドルウェアです//可能であればより良いものへの挨拶(ctx Context.context、w http.responsewriter、r *http.request)context.context {if tag tag 、_、err:= language.parseacceptlanguage(r.header.get( "Accept-Language")); err == nil {for _、t:= range tag {if g、ok:= greetings [t]; ok {ctx = withcontext(ctx、g)return ctx } } } return ctx} // } // fromContextこのコンテキストから挨拶を取得する//または欠落している場合は空の文字列を返します。func fromcontext.context.context)string {hello、_:= ctx.value(key)。(string)return hello}
kami.Get("/path", handler)
kami.Post(...)
など/files/*path
使用してルートを設定します/hello/:name/edit
、そしてそれらにアクセスするコンテキストを使用して、Kamiはあなたに与えます: kami.Param(ctx, "name")
。ルーティングルールとルーティングの優先順位を参照してください。次の種類のハンドラーが受け入れられます。
kami.ContextHandler
を実装するタイプ
func(context.Context, http.ResponseWriter, *http.Request)
http.Handler
を実装するタイプ
func(http.ResponseWriter, *http.Request)
Kamiが使用するすべてのコンテキストは、 kami.Context
の子孫です。これは「神のオブジェクト」であり、このプロジェクトの名前です。デフォルトでは、これはcontext.Background()
ですが、アプリケーションに適した前向きなコンテキストに自由に置き換えてください。
Google App Engineをターゲットにする構築は、App Engineのリクエストごとのコンテキストで「God Object」コンテキストを自動的にラップします。
kami.Use("/path", kami.Middleware)
でミドルウェアを追加します。ミドルウェアはリクエストの前に実行され、早めに停止できます。以下のミドルウェアの詳細。
kami.After("/path", kami.Afterware)
で次のような追加ウェアを追加します。リクエストの後に[死]は実行されます。
kami.Cancel
をtrue
に設定して、リクエストが終了した後にすべてのリクエストのコンテキストを自動的にキャンセルします。標準ライブラリとは異なり、Kamiはデフォルトでコンテキストをキャンセルしません。
kami.PanicHandler
を設定して、パニックハンドラーを提供できます。パニックハンドラーが呼び出されると、 kami.Exception(ctx)
でパニックエラーにアクセスできます。
また、すべてのリクエストをラップするkami.LogHandler
を提供することもできます。 kami.LogHandler
には異なる関数署名があり、応答ステータスコードなどにアクセスできるWriterProxyを使用します。
kami.Serve()
を使用してアプリケーションを優雅に提供するか、 kami.Handler()
どこかに便利な場所にマウントします。
タイプミドルウェアfunc(context.context、http.responsewriter、 *http.request)context.context
ミドルウェアは、新しいコンテキストを返すという点で、ハンドラタイプとは異なります。これを利用して、ApproRiate Pathsでミドルウェアを登録することでコンテキストを構築できます。特別なケースとして、ミドルウェアチェーンの実行を停止するためにnilを返すことができます。
ミドルウェアは階層的です。たとえば、 /hello/greg
のリクエストは、次のパスの下で登録されたミドルウェアを実行します。
/
/hello/
/hello/greg
パス内で、ミドルウェアは登録順に実行されます。
func init(){kami.use( "/"、login)kami.use( "/private/"、loginrequired) } //ログインAppropiateユーザーオブジェクト内のfunfuncログイン(ctx context.context、w http.responsewriter、r *http.request)context.context {if u、err:= user.getbytoken(ctx、r。 formvalue( "auth_token")); err == nil {ctx = user.newcontext(ctx、u) } return ctx} // loginrequiredユーザーObjectFunc loginrequired(ctx context.context、w http.responsewriter、r *http.request)Context.context {if _、ok:= user.fromcontext.fromcontext.fromcontext.fromcontext.context.contex (ctx); !ok {w.writeheader(http.statusforbidden)// ...レンダリング503禁止されたページャーターンnil } ctxを返します}
ミドルウェアの名前付きパラメーターとワイルドカードが現在サポートされています。ワイルドカードのあるパスの下に登録されたミドルウェアは、すべての階層ミドルウェアの後に実行されます。
kami.use( "/user/:id/edit"、checkadminpermissions)// matchesのみ/user/:id/editkami.use("/user/:id/edit/* "、checkadminpermissions)//すべての継承パスを一致させる、非パラメーター化されたパスのように動作します
KamiはバニラHTTPミドルウェアも使用できます。 kami.Use
func(next http.Handler) http.Handler
の形で関数を受け入れます。 Kamiは、チェーンではなく、そのようなミドルウェアを順番に実行することをお勧めします。これは、標準のロガーとパニックハンドラーが期待どおりに機能しないことを意味します。代わりに、 kami.LogHandler
とkami.PanicHandler
使用する必要があります。
次の例では、goji/httpauthを使用して、 /secret/
のパスにHTTP基本認証を追加します。
import( "github.com/goji/httpauth""github.com/guregu/kami")func main(){kami.use("/secret/"、httpauth.simplebasicauth(" username "、" password "))kami .get( "/secret/message"、secretmessagehandler)kami.serve() }
タイプアラvwarefunc(context.context、mutil.writerproxy、 *http.request)context.context
func init(){kami.after( "/"、cleanup) }
リクエストハンドラーを追いかけているのは、クリーンアップに役立ちます。アウトウェアは、ミドルウェアの鏡像のようなものです。 Anaverwareは階層的にも実行されますが、ミドルウェアの逆の順序で実行されます。ワイルドカードは、階層的なアウトウェアの前に評価されます。
たとえば、 /hello/greg
のリクエストは、次のパスの下で登録されている細胞を実行します。
/hello/greg
/hello/
/
これにより、特定のパスの下で、 /
で閉じられる可能性のあるリソースを使用する機能が次のようになります。
ミドルウェアとは異なり、 NILを返しても、残りのダーカーが評価されるのを止めません。
kami.After("/path", afterware)
、さまざまな種類の機能をサポートしています。詳細については、 kami.AfterwareType
のドキュメントを参照してください。
*kami.Mux
を使用した独立したスタックKamiはもともと、複雑なWebアプリケーションの複数のパッケージ間の「接着剤」になるように設計されていました。グローバル機能とkami.Context
は、パッケージが一緒に動作する簡単な方法です。ただし、Kamiを別のアプリ内に組み込みサーバーとして使用したい場合は、異なるポートに2つの別々のKamiスタックを提供する場合、またはKami kami.New()
の非グロバルバージョンが便利になる場合があります。
kami.New()
を呼び出すと、完全に独立したkamiスタックである新鮮な*kami.Mux
を返します。 kami.Context
の変更、 kami.Get()
et alに登録されたパス、およびkami.Use()
に登録されたグローバルミドルウェアは、 *kami.Mux
には影響しません。
代わりmux.Get()
、 mux := kami.New()
mux.NotFound()
使用すると、 mux.Context
mux.Use()
できます。
*kami.Mux
http.Handler
を実装しているので、あなたが望むようにそれを使用することができます!
//パッケージ管理者は、管理者パネルのWebサーバープラグインパッケージadminimport( "net/http" "github.com/guregu/kami")//秘密の管理者スタッフフゥンinit(){mux:= kami.new()muxを自動的にマウントします。 Context = admincontextmux.use( "/"、authorize)mux.get( "/admin/memstats"、memorystats) mux.post( "/admin/die"、shutdown)// ... http.handle( "/admin/"、mux) }
mit
httptreemux:ルーター
Goji:Graceful、WriterProxy