package main import ( "github.com/emicklei/go-restful" "log" "net/http" "time" ) type User struct { Id, Name string } type UserList struct { Users []User } // This example show how to create and use the three different Filters (Container,WebService and Route) // When applied to the restful.DefaultContainer, we refer to them as a global filter. // // GET http://localhost:8080/users/42 // and see the logging per filter (try repeating this request) func main() { // install a global (=DefaultContainer) filter (processed before any webservice in the DefaultContainer) restful.Filter(globalLogging) restful.Add(NewUserService()) log.Print("start listening on localhost:8080") log.Fatal(http.ListenAndServe(":8080", nil)) } func NewUserService() *restful.WebService { ws := new(restful.WebService) ws. Path("/users"). Consumes(restful.MIME_XML, restful.MIME_JSON). Produces(restful.MIME_JSON, restful.MIME_XML) // install a webservice filter (processed before any route) ws.Filter(webserviceLogging).Filter(measureTime) // install a counter filter ws.Route(ws.GET("").Filter(NewCountFilter().routeCounter).To(getAllUsers)) // install 2 chained route filters (processed before calling findUser) ws.Route(ws.GET("/{user-id}").Filter(routeLogging).Filter(NewCountFilter().routeCounter).To(findUser)) return ws } // Global Filter func globalLogging(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) { log.Printf("[global-filter (logger)] %s,%s\n", req.Request.Method, req.Request.URL) chain.ProcessFilter(req, resp) } // WebService Filter func webserviceLogging(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) { log.Printf("[webservice-filter (logger)] %s,%s\n", req.Request.Method, req.Request.URL) chain.ProcessFilter(req, resp) } // WebService (post-process) Filter (as a struct that defines a FilterFunction) func measureTime(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) { now := time.Now() chain.ProcessFilter(req, resp) log.Printf("[webservice-filter (timer)] %v\n", time.Now().Sub(now)) } // Route Filter (defines FilterFunction) func routeLogging(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) { log.Printf("[route-filter (logger)] %s,%s\n", req.Request.Method, req.Request.URL) chain.ProcessFilter(req, resp) } // Route Filter (as a struct that defines a FilterFunction) // CountFilter implements a FilterFunction for counting requests. type CountFilter struct { count int counter chan int // for go-routine safe count increments } // NewCountFilter creates and initializes a new CountFilter. func NewCountFilter() *CountFilter { c := new(CountFilter) c.counter = make(chan int) go func() { for { c.count += <-c.counter } }() return c } // routeCounter increments the count of the filter (through a channel) func (c *CountFilter) routeCounter(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) { c.counter <- 1 log.Printf("[route-filter (counter)] count:%d", c.count) chain.ProcessFilter(req, resp) } // GET http://localhost:8080/users // func getAllUsers(request *restful.Request, response *restful.Response) { log.Print("getAllUsers") response.WriteEntity(UserList{[]User{{"42", "Gandalf"}, {"3.14", "Pi"}}}) } // GET http://localhost:8080/users/42 // func findUser(request *restful.Request, response *restful.Response) { log.Print("findUser") response.WriteEntity(User{"42", "Gandalf"}) }