我是如何在 Go 中构建 Web 服务的( 二 )

HTTP 管道设置在 BindRoutes() 函数中完成,该函数通过 ser.Start() 注入到服务(server)中 。
func BindRoutes(srv webserver.Server, r *mux.Router) {    r.Use(middleware.Metrics(), middleware.Authentication(srv))    r.HandleFunc("/ping", routes.Ping()).Methods(http.MethodGet)    ...    r.HandleFunc("/makes/{makeID}/models/{modelID}", model.get(srv)).Methods(http.MethodGet)}中间件中间件(Middleware)返回一个带有 handler 的函数,handler 用来构建需要的 http.HandlerFunc 。这使得 webserver.Server 接口被注入,同时所有的安静检查只在启动时执行,而不是在所有路由调用的时候 。
func Authentication(srv webserver.Server) func(h http.Handler) http.Handler {    if srv == nil || !srv.Client.IsValid() {        log.Fatal().Msg("a nil dependency was passed to authentication middleware")    }    // additional setup logic    ...    return func(next http.Handler) http.Handler {        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {            token := strings.TrimSpace(r.Header.Get("Authorization"))            if err := srv.ValidateJWT(token); err != nil {                ...                w.WriteHeader(401)                w.Write([]byte("Access Denied"))                return            }            next.ServeHTTP(w, r)        }    }}路由路由有着与中间件有着类似的套路——简单的设置,但是有着同样的收益 。
func GetLatest(srv webserver.Server) http.HandlerFunc {    if srv == nil {        log.Fatal().Msg("a nil dependency was passed to the `/makes/{makeID}/models/{modelID}` route")    }    // additional setup logic    ...    return func(w http.ResponseWriter, r *http.Request) {        ...        makeDTO, err := srv.Get    }}目录结构代码的目录结构对可发现性进行了


推荐阅读