httprouter icon indicating copy to clipboard operation
httprouter copied to clipboard

type Handle to interface

Open neumachen opened this issue 8 years ago • 1 comments

Can we switch to be an interface? Because I tend to use custom handlers that have a base so that I'll have a single place to catch things.

Example:

	router := httprouter.New()

	router.Handle(
		"POST",
		"/api/foo/moo",
		&handler.Base{
			H: handler.MooMoo,
			Opts: &handler.Opts{
				DB:       opt.DB,
				FS:       opt.FS,
				Lgr:      opt.Lgr,
			},
		},
	)

neumachen avatar Sep 25 '17 14:09 neumachen

Do you just need some data accessible to handlers? You could rework your example to something like this:

// Server ...
type Server {
    DB *sql.DB
    FS foo
    Lgr bar
}

// MooMoo handles requests for ...
func (s *Server) handleMooMoo(w http.ResponseWriter, r *http.Request) {
    // s.DB, s.FS, s.LGR
    w.Write([]byte("moo"))
}

s := NewServer(db, fs, logger)
router := httprouter.New()
router.Handle("POST", "/api/foo/moo", s.handleMooMoo)

If you need something custom per handler, you could create a function that takes options and returns a handler:

MooMooHandler(db *sql.Db, fs foo, logger bar) httprouter.Handler {
    return func(http.ResponseWriter, r *http.Requests, p httprouter.Params) {
        // db, fs, logger
        w.Write([]byte("hi"))
    }
}

router := httprouter.New()
router.Handle("POST", "/api/foo/moo", MooMooHandler(db, fs, logger))

Or a combination of both if you need things like a global db handler/logger, and handler-specific data.

cristiangraz avatar Oct 20 '17 19:10 cristiangraz