func main() { list := karambie.List() route := mux.NewRouter() // use gorilla as router martini := martinihelper.New() // and also martini as middleware, see below currentDir, _ := os.Getwd() log := log.New(os.Stdout, "[Karambie] ", 0) logger := logger.New(log, false) // log every request recovery := recovery.New(log, nil) // recover if panic notfoundhandler := notfoundhandler.New(true, nil) // show 404, add trailing slash to url if necessary static := static.New(filepath.Join(currentDir, "public"), log) // serve static file in folder "public" // register logger service for martini martini.Map(log) // the list is immutable, every calling to Add or AddFunc will create new list list = list.Add(logger, recovery) list = list.Add(karambie.Later(notfoundhandler)) list = list.Add(karambie.Later(static)) // or you can use karambie/middleware.Common() to build those list // list is [logger, recovery, notfoundhandler, static] // but the order of execution is [logger, recovery, static, notfoundhandler] // karambie.Later will create new handler that will be executed after succeeding handler // list processing will stop if one of them respond the request (http response status != 0) secureList := list.Add(martini.Conv(auth.Basic("user", "pass"))) // execution of secureList is [logger, recovery, auth, static, notfoundhandler] list = list.Add(martini.Conv(render.Renderer())) // execution of list is [logger, recovery, render, static, notfoundhandler] // list != secureList, because it is immutable, every calling to Add or AddFunc will create new list // using http.HandlerFunc style route.Handle("/helloworld", list.AddFunc(hello)) // [logger, recovery, render, hello] // 'static' and 'notfoundhandler' will be ignored because 'hello' response the request // we can user list as NotFoundHandler (handle static file, and show error 404 if necessary) route.NotFoundHandler = list // [logger, recovery, static, notfoundhandler] // 'notfoundhandler' will be ignored if 'static' response the request // using martini.Handler style and gorilla routing route.Handle("/sayhi/{name}", list.Add(martini.Conv(sayhi))) // [logger, recovery, render, sayhi] // use secureList for sensitive resource route.Handle("/secret", secureList.AddFunc(secret)) // [logger, recovery, auth, secret] // add filterheader to list apiList := list.AddFunc(filterheader) // execution of apiList is [logger, recovery, filterheader, static, notfoundhandler] route.Handle("/api", apiList.AddFunc(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { // this handler will not be called if 'filterheader' is not passed // get apikey ctx := karambie.Context(rw) key := ctx.Get("apikey").(string) fmt.Fprintln(rw, "Your api key : "+key) }))) http.ListenAndServe(":3000", route) }
// get common HandlerList, it contain [logger, recovery, notfoundhandler, static] func Common() (karambie.HandlerList, *log.Logger) { tag := filepath.Base(os.Args[0]) log := log.New(os.Stdout, "["+tag+"] ", 0) cwd, _ := os.Getwd() list := karambie.List( logger.New(log, false), recovery.New(log, nil), karambie.Later(notfoundhandler.New(true, nil)), karambie.Later(static.New(filepath.Join(cwd, "public"), log)), ) return list, log }