Home >Backend Development >Golang >Set different middleware for sub-routes in go-chi

Set different middleware for sub-routes in go-chi

王林
王林forward
2024-02-09 10:06:08739browse

Set different middleware for sub-routes in go-chi

In go-chi, the web framework of Go language, setting different middleware for sub-routes is a common requirement. Middleware is a function that handles HTTP requests and responses and can perform some additional operations before and after the request reaches the target processor. By setting different middleware for different sub-routes, we can personalize each sub-route according to business needs. In this article, we will introduce how to flexibly set up different middleware for sub-routes in go-chi to achieve more flexible routing processing.

Question content

I have a proxy server that can be deactivated through configuration, using mustBeSecure. I want this proxy to behave differently in a certain subdomain: "/application/health", making it always unsafe. All changes I've tried so far have failed. Is there a way to configure a different group for "/application/health" that still uses the proxy but never requires authentication?

router := chi.NewRouter()
router.Route("/", func(r chi.Router) {
    r.Use(chimw.Recoverer)
    router.Use(hlog.NewHandler(log.Logger))
    if mustBeSecure() {
        r.Use(keycloak.MustStandardKeycloakAuth("url"))
    }
    setProxy(r)
    r.Group(func(r chi.Router) {
        r.Get("/health", handleHealth())
    })
})
return http.ListenAndServe("0.0.0.0", router)

As requested, here is an example of setProxy()

func setProxy(r chi.Router) {
    r.Route("/application", func(r chi.Router) {
        r.Use(func(next http.Handler) http.Handler {
            return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                ctx := context.WithValue(r.Context(), "target", "http:locahost:9999")
                r = r.WithContext(ctx)
                next.ServeHTTP(w, r)
            })
        })
        r.HandleFunc("/*", httputil.ReverseProxy{}.ServeHTTP)
    })
}

Workaround

I believe you are trying this.

  • Use router for all /application
  • routes
  • Statement GET /health
  • Create a group (in /application) for all other routes
  • Application condition middleware

For ease of understanding, I have simplified the code slightly. You can still use the setProxy function.

func main() {
    proxy, err := NewProxy("http://localhost:4422")
    if err != nil {
        panic(err)
    }

    router := chi.NewRouter()

    router.Get("/health", handleHealth)

    router.Route("/application", func(r chi.Router) {
        r.Get("/health", ProxyRequestHandler(proxy))

        r.Group(func(r chi.Router) {
            if mustBeSecure() {
                r.Use(keycloak.MustStandardKeycloakAuth("url"))
            }
            r.HandleFunc("/*", ProxyRequestHandler(proxy))
        })
    })

    http.ListenAndServe("0.0.0.0:4411", router)
}

func NewProxy(targetHost string) (*httputil.ReverseProxy, error) {
    targetUrl, err := url.Parse(targetHost)
    if err != nil {
        return nil, err
    }

    return httputil.NewSingleHostReverseProxy(targetUrl), nil
}

func ProxyRequestHandler(proxy *httputil.ReverseProxy) func(http.ResponseWriter, *http.Request) {
    return func(w http.ResponseWriter, r *http.Request) {
        proxy.ServeHTTP(w, r)
    }
}

The above is the detailed content of Set different middleware for sub-routes in go-chi. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete