At some point in your web application, when you are given a request, you will need to perform actions and provide a response to the request. Within the net/http package, there is an http.Handler interface which is implementable, allowing a common entry point scheme for the web server to run your handler code. The Go web server implementation effectively takes a handler you specify, and for each request it runs your handler's ServeHTTP method, which is defined in the interface. As seen in the documentation (https://golang.org/pkg/net/http/#Handler) the handler's ServeHTTP method signature includes a parameter for a http.ResponseWriter interface as well as a pointer to the http.Request structure. The following is an example handler implementation, which can be found at https://github.com/PacktPublishing/Echo-Essentials/tree/master/chapter1/SimpleHandler.go:
package main
import "net/http"
func main() {
http.Handle("/", new(myHandler))
http.ListenAndServe(":8080", nil)
}
type myHandler struct{}
func (mh *myHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
w.Write([]byte("hello!"))
}
Within the preceding example, we are creating a handler type called myHandler, which implements the handler interface. In the implementation of myHandler.ServeHTTP, we are writing hello! as the response body back to the caller. To exercise this handler, you can run this code with go run SimpleHandler.go and then do the same in another terminal running curl localhost:8080/, which will make a request to this service.
Though simple, this example outlines a number of concerns for web application developers. One primary concern is wondering how you can use URL path variables such as /resource/$ID, where $ID would be a variable within your handler. What happens if your code panics within your handler? Are you responsible for encoding all of your response body payload into a []byte type? How can you implement reusability if you need to run the same processes across multiple handlers?