Maison >développement back-end >Golang >Comment implémenter rapidement le framework Go Http Server ? Fait en un seul article
Cet article vous présentera les connaissances pertinentes sur Golang et expliquera comment implémenter rapidement le framework Go Http Server. J'espère qu'il vous sera utile.
Si vous souhaitez utiliser le serveur http dans Go, le moyen le plus simple est d'utiliser http/net
err := http.ListenAndServe(":8080", nil)if err != nil { panic(err.Error())}http.HandleFunc("/hello", func(writer http.ResponseWriter, request *http.Request) { writer.Write([]byte("Hello"))})
pour définir la fonction handle [Recommandations associées : Tutoriel vidéo Go]
tapez HandlerFunc func(ResponseWriter, * Request) code><code>type HandlerFunc func(ResponseWriter, *Request)
标准库的 http 服务器实现很简单,开启一个端口,注册一个实现HandlerFunc
HandlerFunc
En même temps, la bibliothèque standard fournit également un. méthode pour reprendre complètement la requête
func main() { err := http.ListenAndServe(":8080", &Engine{}) if err != nil { panic(err.Error()) }}type Engine struct {}func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/hello" { w.Write([]byte("Hello")) }}Define ServerHTTP
type Handler interface { ServeHTTP(ResponseWriter, *Request)}Si nous devons écrire un framework de serveur HTTP, alors nous devons implémenter cette méthode en même temps, les flux d'entrée et de sortie de net/http ne sont pas très. pratique. Nous avons également besoin d'un packaging, ainsi que d'un simple Route. N'écrivez pas Path dans ServeHTTP. Voici un bref résumé
import ( "net/http")type Engine struct { addr string route map[string]handFunc}type Context struct { w http.ResponseWriter r *http.Request handle handFunc}type handFunc func(ctx *Context) errorfunc NewServer(addr string) *Engine { return &Engine{ addr: addr, route: make(map[string]handFunc), }}func (e *Engine) Run() { err := http.ListenAndServe(e.addr, e) if err != nil { panic(err) }}func (e *Engine) Get(path string, handle handFunc) { e.route[path] = handle}func (e *Engine) handle(writer http.ResponseWriter, request *http.Request, handle handFunc) { ctx := &Context{ w: writer, r: request, handle: handle, } ctx.Next()}func (e *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) { handleF := e.route[req.URL.Path] e.handle(w, req, handleF)}func (c *Context) Next() error { return c.handle(c)}func (c *Context) Write(s string) error { _, err := c.w.Write([]byte(s)) return err}Nous écrivons un test pour vérifier notre serveur Http
func TestHttp(t *testing.T) { app := NewServer(":8080") app.Get("/hello", func(ctx *Context) error { return ctx.Write("Hello") }) app.Run()}Le handle que nous emballons ici utilise le mode d'erreur de retour. Par rapport à la bibliothèque standard, il écrit uniquement mais ne renvoie pas This. évite le problème de l'oubli de retour après ne pas avoir écrit des erreurs, souvent difficiles à repérer. Un serveur HTTP a également besoin d'une fonction middleware. L'idée ici est de stocker un tableau de handleFunc dans le moteur, de prendre en charge l'enregistrement externe, de créer un nouveau Ctx lorsqu'une demande arrive et de copier le HandleFunc global dans le moteur vers le Ctx. , puis utilisez c.Next() pour implémenter les appels de style matriochka.
package httpimport ( "net/http")type Engine struct { addr string route map[string]handFunc middlewares []handFunc}type Context struct { w http.ResponseWriter r *http.Request index int handlers []handFunc}type handFunc func(ctx *Context) errorfunc NewServer(addr string) *Engine { return &Engine{ addr: addr, route: make(map[string]handFunc), middlewares: make([]handFunc, 0), }}func (e *Engine) Run() { err := http.ListenAndServe(e.addr, e) if err != nil { panic(err) }}func (e *Engine) Use(middleware handFunc) { e.middlewares = append(e.middlewares, middleware)}func (e *Engine) Get(path string, handle handFunc) { e.route[path] = handle}func (e *Engine) handle(writer http.ResponseWriter, request *http.Request, handle handFunc) { handlers := make([]handFunc, 0, len(e.middlewares)+1) handlers = append(handlers, e.middlewares...) handlers = append(handlers, handle) ctx := &Context{ w: writer, r: request, index: -1, handlers: handlers, } ctx.Next()}func (e *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) { handleF := e.route[req.URL.Path] e.handle(w, req, handleF)}func (c *Context) Next() error { c.index++ if c.index < len(c.handlers) { return c.handlers[c.index](c) } return nil}func (c *Context) Write(s string) error { _, err := c.w.Write([]byte(s)) return err}La méthode d'implémentation est très simple. Ici, nous vérifions si elle peut prendre en charge le pré- et le post-middleware
func TestHttp(t *testing.T) { app := NewServer(":8080") app.Get("/hello", func(ctx *Context) error { fmt.Println("Hello") return ctx.Write("Hello") }) app.Use(func(ctx *Context) error { fmt.Println("A1") return ctx.Next() }) app.Use(func(ctx *Context) error { err := ctx.Next() fmt.Println("B1") return err }) app.Run()}Sortie :
=== RUN TestHttp A1 Hello B1Avec seulement 100 lignes de code au total, nous avons implémenté un simple serveur HTTP. allez aux détails de suivi En regardant le code source de Gin, l'accent est mis sur Route et l'implémentation de l'arborescence des préfixes. 🎜
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!