import "github.com/guregu/kami"
oder import "gopkg.in/guregu/kami.v2"
Kami (神) ist ein winziges Web -Framework, das den Kontext für Anforderungskontext und httpTreemux für Routing verwendet. Es enthält ein einfaches System zum Ausführen hierarchischer Middleware vor und nach Anforderungen, zusätzlich zu Protokoll- und Panikhaken. Der anmutige Neustart über Einhorn wird ebenfalls unterstützt.
Kami ist so konzipiert, dass sie als zentraler Registrierungspunkt für Ihre Routen, Ihre Middleware und Ihren Kontext "Gott -Objekt" verwendet werden. Sie werden ermutigt, die globalen Funktionen zu verwenden, aber Kami unterstützt mehrere Muxen mit kami.New()
.
Sie stehen frei zu montieren kami.Handler()
wo immer Sie möchten, aber eine hilfreiche kami.Serve()
-Funktion wird bereitgestellt.
Hier ist eine Präsentation über die Geburt von Kami, die einige der Designentscheidungen erklärt.
Sowohl context
als auch x/net/context
werden unterstützt.
Ein erfundenes Beispiel unter Verwendung von Kami und Kontext, um Grüße zu lokalisieren.
Überspringen ⏩
// Unser Webserverpackage Mainimport ("fmt" net/http "" Kontext "" github.com/guregu/kami "" Github.com/my-github/greeting "// Siehe Paket Gruß unten) Func Greet (CTX-Kontext. Kontext, w http.responsewriter, r *http.request) {hello: = Begrüßung.FromContext (CTX) Name: = Kami.param (CTX, "Name") fmt.fprintf (W, " %s, %s!", Hallo, Name) } func main () {ctx: = context.background () ctx = greeting.withContext (ctx, "hello") // Setzen Sie die Standardgrüßkami.Context = CTX // Setzen .Use ("/Hallo/", Gruß.guess) // Verwenden Sie diese Middleware für Pfade unter /hello/kami.get("/hello/:Name ", begrüßen) // einen Get Handler mit einem Parameter in der urlkami.serve () // anmutig mit Unterstützung für Einhorn und Systemd} dienen} dienen
// Paket Grußgeschäfte Begrüßungseinstellungen in Context.package Begrüßung ("net/http" "Kontext" "golang.org/x/text/Language") // Weitere Informationen zum Kontext und warum wir dies tun, // // siehe https://blog.golang.org/contextType ctxkey intvar key ctxkey = 0var greetings = Karte [Sprache.tag] String {Language.americanenglish: "Yo", Language.japanese: "こんにちは", } // gilt ist Kami Middleware, die die Akzeptanz-Sprache untersucht und // die Begrüßung auf eine bessere, wenn möglich. , _, err: = Sprache.ParseAcceptLuGuage (R.Header.get ("Akzeptieren Sie Sprache")); err == nil {für _, t: = range tag {if g, ok: = gründen [t]; OK {ctx = withContext (ctx, g) return ctx return } } } return ctx} // WithContext gibt einen neuen Kontext mit der angegebenen Begrüßung zurück. } // From Context ruft die Begrüßung aus diesem Kontext ab, // oder gibt einen leeren String zurück, wenn fehlend.func von context (ctx context.context) String {hello, _: = ctx.value (taste). (String) return hello}
Richten Sie Routen mit kami.Get("/path", handler)
, kami.Post(...)
usw. Sie können benannte Parameter oder Platzhalter in URLs wie /hello/:name/edit
oder /files/*path
verwenden und greifen Sie mit dem Kontext, den Kami Ihnen gibt: kami.Param(ctx, "name")
. Siehe die Routing -Regeln und die Routing -Priorität. Die folgenden Arten von Handlern werden akzeptiert:
Typen, die kami.ContextHandler
implementieren
func(context.Context, http.ResponseWriter, *http.Request)
Typen, die http.Handler
implementieren
func(http.ResponseWriter, *http.Request)
Alle Kontexte, die Kami verwendet, stammen von kami.Context
: Dies ist das "Gott -Objekt" und der Namensgeber dieses Projekts. Standardmäßig ist dies context.Background()
, ersetzen Sie ihn jedoch durch einen voreinitialisierten Kontext, der für Ihre Anwendung geeignet ist.
Builds Targeting-Google App Engine wickelt automatisch den Kontext "Gott Objekt" mit dem Kontext der App-Engine.
Fügen Sie Middleware mit kami.Use("/path", kami.Middleware)
. Middleware läuft vor Anfragen und kann sie frühzeitig stoppen. Mehr über Middleware unten.
Fügen Sie mit kami.After("/path", kami.Afterware)
nach Afterware hinzu. Afterware läuft nach Anfragen.
Setzen Sie kami.Cancel
auf true
, um nach Abschluss der Anfrage automatisch alle Kontexte aller Anforderungen abzubrechen. Im Gegensatz zur Standardbibliothek storniert Kami die Kontexte standardmäßig nicht.
Sie können einen Panik -Handler bereitstellen, indem Sie kami.PanicHandler
einstellen. Wenn der Panikhandler aufgerufen wird, können Sie mit kami.Exception(ctx)
auf den Panikfehler zugreifen.
Sie können auch einen kami.LogHandler
zur Verfügung stellen, der jede Anfrage einpackt. kami.LogHandler
hat eine andere Funktionssignatur, die eine WriterProxy nimmt, die Zugriff auf den Antwortstatuscode usw. hat, usw.
Verwenden Sie kami.Serve()
, um Ihre Bewerbung anmutig zu bedienen, oder montieren Sie kami.Handler()
an einem praktischen Ort.
Typ Middleware func (context.context, http.responsewriter, *http.request) context.context
Middleware unterscheidet sich von einem Handlertyp darin, dass er einen neuen Kontext zurückgibt. Sie können dies nutzen, um Ihren Kontext zu erstellen, indem Sie Middleware auf den Aufladungspfaden registrieren. Als Sonderfall können Sie NIL zurückgeben, um die Ausführung der Middleware -Kette zu stoppen.
Middleware ist hierarchisch. Beispielsweise wird eine Anfrage für /hello/greg
Middleware aus den folgenden Pfaden ausführen, in der Reihenfolge:
/
/hello/
/hello/greg
In einem Pfad wird Middleware in der Reihenfolge der Registrierung ausgeführt.
Func init () {Kami.use ("/", Login) Kami.use ("/privat/", LoginRequired) } // Login gibt einen neuen Kontext mit dem anerkennenden Benutzerobjekt in der Anmeldung (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 stoppt die Anforderung, wenn wir keine Benutzerobjektfunc -LoginRequired (ctx context.context, w http.Responsewriter, r *http.Request) context.context {if _, OK: = user.fromcontext haben. (CTX); ! OK {W.WriteHeader (http.statusforbidden) // ... Render 503 Forbidden Pagereturn nil rendern } return ctx}
Die benannten Parameter und Wildcards in Middleware werden jetzt unterstützt. Middleware, die unter einem Pfad mit einer Wildcard registriert ist, wird nach allen hierarchischen Middleware ausgeführt.
Kami.use ("/user/: id/edit", checkAdminpermissions) // passt nur /user/:id/editkami.use("/user/:id/edit/* , verhält sich wie nicht parametrisierte Wege
Kami kann auch Vanilla http Middleware verwenden. kami.Use
akzeptiert Funktionen in Form von func(next http.Handler) http.Handler
. Beachten Sie, dass Kami solche Middleware in Sequenz ausführen wird, nicht in einer Kette. Dies bedeutet, dass Standard -Logger und Panikhandler nicht wie erwartet funktionieren. Sie sollten stattdessen kami.LogHandler
und kami.PanicHandler
verwenden.
Das folgende Beispiel verwendet Goji/HttpAuth, um die HTTP -Basisauthentifizierung zu Pfaden unter /secret/
zu fügen.
Import ("github.com/goji/httpautpaut""github.com/guregu/kami")func main () {Kami.use ("/geheime/", httpauth.simpleBasicauth (" Benutzername "," Passwort ") Kami Kami Kami Kami Kami Kami Kami Kami. Kami Kami .Get ("/Secret/Message", SecretMessageHandler) Kami.serve () }
Typ Afterware Func (context.context, mutil.writerProxy, *http.request) context.context
func init () {Kami.after ("/", Reinigung) }
Nach dem Anforderungshandler ist Afterware nützlich für die Reinigung. Afterware ist wie ein Spiegelbild von Middleware. Afterware läuft auch hierarchisch, jedoch in umgekehrter Reihenfolge von Middleware. Wildcards werden vor hierarchischen Afterware ausgewertet.
Beispielsweise wird eine Anfrage für /hello/greg
nach den folgenden Pfaden ausführen:
/hello/greg
/hello/
/
Dadurch gibt es nach Bedarf unter bestimmten Pfaden die Möglichkeit, Ressourcen zu verwenden, die von /
geschlossen werden können.
Im Gegensatz zu Middleware verhindern die nachweisende NIL -Rückgabe die verbleibende Aftergeschirr nicht.
kami.After("/path", afterware)
unterstützt viele verschiedene Arten von Funktionen. Weitere Informationen finden Sie in den Dokumenten für kami.AfterwareType
.
*kami.Mux
Kami wurde ursprünglich als "Kleber" zwischen mehreren Paketen in einer komplexen Webanwendung entwickelt. Die globalen Funktionen und kami.Context
sind eine einfache Möglichkeit für Ihre Pakete, zusammenzuarbeiten. Wenn Sie jedoch Kami als eingebetteten Server in einer anderen App verwenden möchten, zwei separate Kami-Stapel an verschiedenen Ports servieren oder auf andere Weise eine nicht-globale Version von Kami, kami.New()
können sich nützlich erweisen.
Calling kami.New()
gibt einen frischen *kami.Mux
zurück, einen völlig unabhängigen Kami -Stack. Änderungen an kami.Context
, bei kami.Get()
et al. Und Global Middleware bei kami.Use()
haben A *kami.Mux
nicht beeinflusst.
Stattdessen können Sie mit mux := kami.New()
mux.Context
, rufen Sie mux.Use()
, mux.Get()
, mux.NotFound()
usw. an.
*kami.Mux
implementiert http.Handler
, sodass Sie es verwenden können, wie Sie möchten!
// Package Admin ist ein Admin -Panel Web Server PluginPackage Adminimport ("net/http" "" github.com/guregu/kami ") // automatisch unseren geheimen Administrator -Stufffunc init () {mux: = Kami.new () mux montieren. Context = admincontextmux.use ("/", autorize) mux.get ("/admin/memstats", meenStats) mux.post ("/admin/Die", Herunterfahren) // ... http.handle ("/admin/", mux) }
MIT
httpTreemux: Router
Goji: Anmutig, writerProxy