martini-contrib / render

Martini middleware/handler for easily rendering serialized JSON, XML, and HTML template responses.
MIT License
245 stars 57 forks source link

Capturing the http.ResponseWriter means Renderer must be the last handler #6

Open tysonstewart opened 10 years ago

tysonstewart commented 10 years ago

I discovered this while trying to implement a cache handler. We don't want to cache all of our requests, so we'd like to pass the cache handler to the router. In order to do this, however, Renderer has to be passed to every route as well and after the cache.

Example:

martiniServer.Use(render.Renderer())
router := martini.NewRouter()
// Caching won't work here because it wants to intercept and
// and replace the http.ResponseWriter, but Render has a
// reference to the original ResponseWriter. The replaced one
// will never be used.
router.Get("/", cache, func(r render.Render) {
    r.HTML(200, "index", "Welcome")
}

Is it necessary to capture the ResponseWriter? Is there a better way to do what I'm trying to do?

codegangsta commented 10 years ago

This is because render uses the ResponseWriter that is injected into it's handler function.

render.Renderer could grab the ResponseWriter from the context right before it renders things, but that would require some changes and introduce some undesired behavior. I'm willing to explore the idea given that it doesn't break existing functionality