import "github.com/guregu/kami"
ou import "gopkg.in/guregu/kami.v2"
Kami (神) est un minuscule framework Web utilisant le contexte pour le contexte de demande et httptreemux pour le routage. Il comprend un système simple pour l'exécution du middleware hiérarchique avant et après les demandes, en plus des crochets de journal et de panique. Le redémarrage gracieux via Einhorn est également soutenu.
Kami est conçu pour être utilisé comme point d'enregistrement central pour vos itinéraires, middleware et contexte "God Object". Vous êtes encouragé à utiliser les fonctions globales, mais KAMI prend en charge plusieurs muxs avec kami.New()
.
Vous êtes libre de monter kami.Handler()
partout où vous le souhaitez, mais une fonction kami.Serve()
utile est fournie.
Voici une présentation sur la naissance de Kami, expliquant certains des choix de conception.
Le context
et x/net/context
sont pris en charge.
Un exemple artificiel utilisant Kami et le contexte pour localiser les salutations.
Sauter ⏩
// Notre WebServerPackage MainIMPort ("FMT" "Net / HTTP" "Context" "github.com/guregu/kami" "github.com/my-github/greeting" // voir le package de salutation ci-dessous) Func Greet (CTX Context. Context, w http.ResponseWriter, r * http.request) {Bonjour: = Greeting.fromContext (CTX) Nom: = Kami.Param (CTX, "Name") FMT.Fprintf (W, "% S,% S!", Bonjour, nom) } func main () {ctx: = context.background () ctx = salutation.withContex .Use ("/ Hello /", Greeting.Guess) // Utilisez ce middleware pour les chemins sous /hello/kami.get("/hello/:name ", saluer) // ajouter un gestionnaire de get avec un paramètre dans Urlkami.serve () // servir gracieusement avec le support pour Einhorn et Systemd}
// Package Greeting Stores Paramètres de salutation dans Context.Package GreetingImport ("net / http" "context" "golang.org/x/text/language") // pour plus d'informations sur le contexte et pourquoi nous faisons cela, // Voir https://blog.golang.org/contextType ctxkey intvar key ctxkey = 0var salutings = map [lingngle.tag] string { Langue.AmericanEnglish: "Yo", Language.Japanais: "こんにちは", } // Deviness est le middleware kami qui examine l'accept-lang et set // la salutation à une meilleure si possible.func deviner (ctx context.context, w http.responsewriter, r * http.request) context.context {if tag , _, err: = Language.PaSeAcceptLanguage (R.Header.get ("Accept-Language")); err == nil {pour _, t: = range tag {si g, ok: = salutations [t]; ok {ctx = withContext (ctx, g) return ctx } } } return ctx} // withContext renvoie un nouveau contexte avec le Greeting.Func avecContex } // DeContext récupère la salutation à partir de ce contexte, // ou renvoie une chaîne vide si manquant.func fromContext (ctx context.context) String {bonjour, _: = ctx.value (key). (String) return hello}
Configurer des routes à l'aide de kami.Get("/path", handler)
, kami.Post(...)
, etc. Vous pouvez utiliser des paramètres nommés ou des wildcards dans des URL comme /hello/:name/edit
ou /files/*path
et accéder à leur accéder en utilisant le contexte que Kami vous donne: kami.Param(ctx, "name")
. Voir les règles de routage et la priorité du routage. Les types de gestionnaires suivants sont acceptés:
Types qui implémentent kami.ContextHandler
func(context.Context, http.ResponseWriter, *http.Request)
types qui implémentent http.Handler
func(http.ResponseWriter, *http.Request)
Tous les contextes utilisés par Kami sont issus de kami.Context
: Ceci est «l'objet Dieu» et l'homonyme de ce projet. Par défaut, c'est context.Background()
, mais n'hésitez pas à le remplacer par un contexte pré-initialisé adapté à votre application.
Les créations de création de moteur Google App enveloppement automatiquement le contexte "God Object" avec le contexte par la demande de request du moteur App.
Ajoutez du middleware avec kami.Use("/path", kami.Middleware)
. Le middleware s'exécute avant les demandes et peut les arrêter tôt. En savoir plus sur le middleware ci-dessous.
Ajouter Afterware avec kami.After("/path", kami.Afterware)
. Afterware s'exécute après les demandes.
Définissez kami.Cancel
sur true
pour annuler automatiquement tous les contextes de la demande une fois la demande terminée. Contrairement à la bibliothèque standard, Kami n'annule pas les contextes par défaut.
Vous pouvez fournir un gestionnaire de panique en définissant kami.PanicHandler
. Lorsque le gestionnaire de panique est appelé, vous pouvez accéder à l'erreur de panique avec kami.Exception(ctx)
.
Vous pouvez également fournir un kami.LogHandler
qui enveloppera chaque demande. kami.LogHandler
a une signature de fonction différente, en prenant un écrivainProxy qui a accès au code d'état de la réponse, etc.
Utilisez kami.Serve()
pour servir gracieusement votre demande, ou monter kami.Handler()
dans un endroit pratique.
Type middleware func (context.context, http.ResponseWriter, * http.request) context.context
Le middleware diffère d'un HandlerType en ce qu'il renvoie un nouveau contexte. Vous pouvez en profiter pour construire votre contexte en enregistrant le middleware sur les chemins d'approche. En tant que cas spécial, vous pouvez retourner nil pour arrêter l'exécution de la chaîne de middleware.
Le middleware est hiérarchique. Par exemple, une demande pour /hello/greg
exécutera le middleware enregistré dans les chemins suivants, dans l'ordre:
/
/hello/
/hello/greg
Dans un chemin, le middleware est exécuté dans l'ordre d'enregistrement.
func init () {kami.use ("/", login) kami.use ("/ private /", loginrequired) } // Login renvoie un nouveau contexte avec l'objet utilisateur approprié à l'intérieur de la connexion (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 arrête la demande si nous n'avons pas d'objet utilisateur LoginRequired (ctx context.context, w http.responsewriter, r * http.request) context.contex (CTX); ! Ok {w.writeHeader (http.statusforbidden) // ... rendu 503 interdit de pages } return ctx}
Les paramètres nommés et les jokers dans le middleware sont maintenant pris en charge. Le middleware enregistré sous un chemin avec un joker fonctionnera après tous les middleware hiérarchiques.
kami.use ("/ user /: id / edit", checkAdMinPerMissions) // correspond uniquement /User/:id/editkami.usecu("/user/:id/edit/* ", checkAdminPerMissions) // correspond à tous les chemins hérités , se comporte comme des chemins non paramétrisés
Kami peut également utiliser le middleware HTTP Vanilla. kami.Use
accepte les fonctions sous forme de func(next http.Handler) http.Handler
. Soyez informé que Kami exécutera un tel middleware en séquence, pas dans une chaîne. Cela signifie que les enregistreurs standard et les gestionnaires de panique ne fonctionneront pas comme vous vous y attendez. Vous devez utiliser kami.LogHandler
et kami.PanicHandler
à la place.
L'exemple suivant utilise Goji / Httpauth pour ajouter l'authentification de base HTTP aux chemins sous /secret/
.
import ("github.com/goji/httpauth""github.com/guregu/kami")func main () {kami.use (" / secret / ", httpauth.simplebasicard (" nom d'utilisateur "," mot de passe ")) kami .Get ("/ Secret / Message", SecretMessageHandler) Kami.serve () }
Tapez après le func (context.context, mutil.writerproxy, * http.request) context.context
func init () {kami.after ("/", nettoyage) }
Exécution après le gestionnaire de demandes, après un logiciel est utile pour le nettoyage. Afterware est comme une image miroir du middleware. Après le logiciel s'exécute également de manière hiérarchique, mais dans l'ordre inverse du middleware. Les caractères génériques sont évalués avant le logiciel hiérarchique.
Par exemple, une demande pour /hello/greg
s'exécutera après le logiciel enregistré dans les chemins suivants:
/hello/greg
/hello/
/
Cela donne après un logiciel sous des chemins spécifiques la possibilité d'utiliser des ressources qui peuvent être fermées par /
.
Contrairement au middleware, Afterware Retour Nil n'empêchera pas le reste de la mise en service.
kami.After("/path", afterware)
prend en charge de nombreux types de fonctions différents, voir les documents de kami.AfterwareType
pour plus de détails.
*kami.Mux
Kami a été initialement conçu pour être la "colle" entre plusieurs packages dans une application Web complexe. Les fonctions globales et kami.Context
sont un moyen facile pour vos packages de fonctionner ensemble. Cependant, si vous souhaitez utiliser Kami comme serveur embarqué dans une autre application, servez deux piles Kami distinctes sur différents ports, ou si vous souhaitez avoir une version non globale de Kami, kami.New()
peut être utile.
L'appel kami.New()
renvoie un nouveau *kami.Mux
, une pile Kami complètement indépendante. Les modifications de kami.Context
, les chemins enregistrés auprès de kami.Get()
et al et le middleware global enregistré avec kami.Use()
n'affecteront pas a *kami.Mux
.
Au lieu de cela, avec mux := kami.New()
vous pouvez modifier mux.Context
, appeler mux.Use()
, mux.Get()
, mux.NotFound()
, etc.
*kami.Mux
implémente http.Handler
, vous pouvez donc l'utiliser comme vous le souhaitez!
// L'administrateur de package est un administrateur de serveur Web de panneau d'administration PluginPackage AdminIMport ("net / http" "github.com/guregu/kami") // monte automatiquement notre administrateur secret sortfunc init () {MUX: = kami.new () MUX. Context = admincontextmux.use ("/", autorise) mux.get ("/ admin / memStats", memorystats) MUX.POST ("/ admin / die", arrêt) // ... http.handle ("/ admin /", MUX) }
Mit
httptreeMux: routeur
Goji: gracieux, écrivainproxy