I\'m using httprouter for an API and I\'m trying to work out how to handle 404s. It does say in the docs that 404\'s can be handled manually but I don\'t really have an idea
The type httprouter.Router is a struct
which has a field:
NotFound http.Handler
So type of NotFound
is http.Handler, an interface type which has a single method:
ServeHTTP(ResponseWriter, *Request)
If you want your own custom "Not Found" handler, you have to set a value that implements this interface.
The easiest way is to define a function with signature:
func(http.ResponseWriter, *http.Request)
And use the http.HandlerFunc() helper function to "convert" it to a value that implements the http.Handler
interface, whose ServeHTTP()
method simply calls the function with the above signature.
For example:
func MyNotFound(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
w.WriteHeader(http.StatusNotFound) // StatusNotFound = 404
w.Write([]byte("My own Not Found handler."))
w.Write([]byte(" The page you requested could not be found."))
}
var router *httprouter.Router = ... // Your router value
router.NotFound = http.HandlerFunc(MyNotFound)
This NotFound
handler will be invoked by the httprouter
package. If you would want to call it manually from one of your other handlers, you would have to pass a ResponseWriter and a *Request to it, something like this:
func ResourceHandler(w http.ResponseWriter, r *http.Request) {
exists := ... // Find out if requested resource is valid and available
if !exists {
MyNotFound(w, r) // Pass ResponseWriter and Request
// Or via the Router:
// router.NotFound(w, r)
return
}
// Resource exists, serve it
// ...
}