Restricting HTTP request methods, when working with net/http prior to Go 1.22 was a little complicated. However, that’s all changed. Now, it’s pretty trivial. In this short tutorial, I’ll show you the new approach.
Recently, I wrote about how to restrict the allowed HTTP request methods in Go.
In short, while not the most intuitive, you need to test what request.Method
is set to, such as in this short example.
mux.HandleFunc("/",
func (writer http.ResponseWriter, request *http.Request) {
if request.Method != "POST" {
writer.Header().Set("Allow", "POST")
http.Error(
writer,
"That method is not allowed.",
http.StatusMethodNotAllowed,
)
return
}
io.WriteString(writer, "Here is a response.")
})
Prior to Go 1.22, any HTTP method could be used to request the route.
But, if the HTTP method was not set to POST
, then the handler above would return an HTTP 404 Not Found.
Only if it was set to POST
, would the request execute successfully, setting the body to Here is a response.
.
There’s nothing wrong with this approach, but, it meant I had to include extra code to check the request method.
Gladly, in Go 1.22, that’s a thing of the past!
This is because, if you read through the routing enhancements, you’ll know that HandleFunc()
, while being backwards compatible, now accepts an HTTP method before the route pattern.
When added, if a request is made to that route with a different HTTP method than the one specified, a 404 Not Found will be returned.
Here’s what the earlier example would look like.
mux.HandleFunc("POST /",
func (writer http.ResponseWriter, request *http.Request) {
io.WriteString(writer, "Here is a response.")
}
)
It’s much shorter and easier to read, thanks to the boilerplate checking code being removed!
Don’t forget to check your go.mod file!
One thing I was caught out by, when trying out the changes, initially , was that I had added module support to my test project using Go version 1.20, but then upgraded version 1.22.
I was surprised when the new routing enhancements didn’t work.
As it turned out, the Go version (in go.mod) was set to 1.20
.
After changing it to 1.22
and restarting the application, the new routing enhancements took effect.
This was the case because, as the go.mod reference states:
The go directive affects use of new language features:
For packages within the module, the compiler rejects use of language features introduced after the version specified by the go directive. For example, if a module has the directive go 1.12, its packages may not use numeric literals like 1_000_000, which were introduced in Go 1.13.
Thanks to Bill Moran from the Gophers Slack channel for reminding me to check for this.
What do you think of the routing enhancement?
Is it an improvement?
For me it is.
Join the discussion
comments powered by Disqus