Open Source
https://github.com/slok/kubewebhook(Go framework to create Kubernetes mutating and validating webhooks.)。是一个用于创建 Kubernetes mutating 和 validating webhook 的 Golang 框架,其中提供了用于生产环境的示例模板。
Sample
https://github.com/shenxianghong/shenxianghong.github.io/tree/main/elegant-code/web-structure
Structure
handlers
handlers 中聚焦实际的业务处理逻辑
welcome.go
请求到来时,组装返回的消息内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| package handlers
import "fmt"
type Welcome interface { Hello() string }
type WelcomeHandler struct { User string }
func (h WelcomeHandler) Hello() string { return fmt.Sprintf("hello %s, welcome.", h.User) }
func NewWelcomeHandler() Welcome { var handler WelcomeHandler handler.User = "Arthur" return handler }
|
goodbye.go
原理类似 welcome.go
web
web 框架的基础结构
handlers.go
调用业务逻辑,构建 http.Handler 类型,作为请求的 handler 函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package web
import "net/http"
func (h handler) welcomeHandler() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { w.Write([]byte(h.welcome.Hello())) w.WriteHeader(http.StatusOK) }) }
func (h handler) goodbyeHandler() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { w.Write([]byte(h.goodbye.Goodbye())) w.WriteHeader(http.StatusOK) }) }
|
router.go
用于注册业务逻辑部分的路由,也就是子路由
1 2 3 4 5 6 7 8 9 10
| package web
import "net/http"
func (h handler) router(router *http.ServeMux) { router.Handle("/welcome", h.welcomeHandler()) router.Handle("/goodbye", h.goodbyeHandler()) return }
|
web.go
web 框架的上层对象,包括配置和根路由 handler 的生成等
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| package web
import ( "elegant-coding/handlers"
"errors" "net/http" )
type Config struct { WelcomeHandler handlers.Welcome GoodbyeHandler handlers.Goodbye }
func (c *Config) defaults() error { if c.WelcomeHandler == nil { return errors.New("welcome handler is missing") } if c.GoodbyeHandler == nil { return errors.New("goodbye handler is missing") } return nil }
type handler struct { welcome handlers.Welcome goodbye handlers.Goodbye handler http.Handler }
func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { h.handler.ServeHTTP(w, r) }
func New(config Config) http.Handler { if err := config.defaults(); err != nil { panic("handler configuration is not valid") }
mux := http.NewServeMux() h := handler{ welcome: config.WelcomeHandler, goodbye: config.GoodbyeHandler, handler: mux, } h.router(mux)
return h }
|
main.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| package main
import ( "fmt" "net/http"
"elegant-coding/handlers" "elegant-coding/web" )
func main() { handler := web.New(web.Config{ WelcomeHandler: handlers.NewWelcomeHandler(), GoodbyeHandler: handlers.NewGoodbyeHandler(), }) mux := http.NewServeMux() mux.Handle("/", handler) server := http.Server{ Addr: ":8081", Handler: mux, } err := server.ListenAndServe() if err != nil { fmt.Println(err.Error()) return } }
|