zeromicro / go-zero

A cloud-native Go microservices framework with cli tool for productivity.
https://go-zero.dev
MIT License
29.43k stars 3.97k forks source link

can not use rest.WithChain in the main, because, it make all built-in middlewares not work #2978

Open xingzhi0504 opened 1 year ago

xingzhi0504 commented 1 year ago

Describe the bug can not use rest.WithChain in the main, because, it make all built-in middlewares not work

  1. The code is

    // main
    server := rest.MustNewServer(
        c.RestConf,
        rest.WithChain(chain.New(
            .....
        )),
    )
    defer server.Stop()
    // rest/engine.go:87
    func (ng *engine) bindRoute(fr featuredRoutes, router httpx.Router, metrics *stat.Metrics,
    route Route, verifier func(chain.Chain) chain.Chain) error {
    chn := ng.chain
    if chn == nil {
        chn = ng.buildChainWithNativeMiddlewares(fr, route, metrics)
    }
    
    chn = ng.appendAuthHandler(fr, chn, verifier)
    
    for _, middleware := range ng.middlewares {
        chn = chn.Append(convertMiddleware(middleware))
    }
    handle := chn.ThenFunc(route.Handler)
    
    return router.Handle(route.Method, route.Path, handle)
    }
kevwan commented 1 year ago

rest.WithChain is designed use all your own middlewares.

If you want to disable some middlewares, you can just disable them in config files.

7134g commented 1 year ago

If I want to implement a custom middleware before the built-in middleware. How to do?

e8244619acbe43fff39ff3e79083a9c

kevwan commented 1 year ago

You can do it like this:

package main

import (
    "fmt"
    "net/http"

    "github.com/zeromicro/go-zero/core/conf"
    "github.com/zeromicro/go-zero/core/logx"
    "github.com/zeromicro/go-zero/rest"
    "github.com/zeromicro/go-zero/rest/httpx"
    "github.com/zeromicro/go-zero/rest/router"
)

type myRouter struct {
    httpx.Router
}

func (r *myRouter) Handle(method, path string, handler http.Handler) error {
    if method == http.MethodGet && path == "/hello" {
        return r.Router.Handle(method, path, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            fmt.Println("pre-handle")
            handler.ServeHTTP(w, r)
        }))
    }

    return r.Router.Handle(method, path, handler)
}

func main() {
    var c rest.RestConf
    logx.Must(conf.FillDefault(&c))
    c.Port = 8888
    server := rest.MustNewServer(c, rest.WithRouter(&myRouter{router.NewRouter()}))
    server.AddRoute(rest.Route{
        Method: http.MethodGet,
        Path:   "/hello",
        Handler: func(w http.ResponseWriter, r *http.Request) {
            w.Write([]byte("hello"))
        },
    })
    server.AddRoute(rest.Route{
        Method: http.MethodGet,
        Path:   "/world",
        Handler: func(w http.ResponseWriter, r *http.Request) {
            w.Write([]byte("world"))
        },
    })
    defer server.Stop()
    server.Start()
}
github-actions[bot] commented 1 month ago

This issue is stale because it has been open for 30 days with no activity.