URL Query Strings
While we’re on the subject of routing, let’s update the
showSnippet handler so that it accepts an
id query string parameter from the user like so:
|ANY||/||home||Display the home page|
|ANY||/snippet?id=1||showSnippet||Display a specific snippet|
|POST||/snippet/create||createSnippet||Create a new snippet|
Later we’ll use this
id parameter to select a specific snippet from a database and show it to the user. But for now, we’ll just read the value of the
id parameter and interpolate it with a placeholder response.
To make this work we’ll need to update the
showSnippet handler function to do two things:
It needs to retrieve the value of the
idparameter from the URL query string, which we can do using the
r.URL.Query().Get()method. This will always return a string value for a parameter, or the empty string
""if no matching parameter exists.
idparameter is untrusted user input, we should validate it to make sure it’s sane and sensible. For the purpose of our Snippetbox application, we want to check that it contains a positive integer value. We can do this by trying to convert the string value to an integer with the
strconv.Atoi()function, and then checking the value is greater than zero.
Let’s try this out.
Restart the application, and try visiting a URL like
http://localhost:4000/snippet?id=123. You should see a response which looks like this:
You might also like to try visiting some URLs which have invalid values for the
id parameter, or no parameter at all. For instance:
For all these requests you should get a
404 page not found response.
The io.Writer Interface
The code above introduced another new thing behind-the-scenes. If you take a look at the documentation for the
fmt.Fprintf() function you’ll notice that it takes an
io.Writer as the first parameter…
…but we passed it our
http.ResponseWriter object instead — and it worked fine.
We’re able to do this because the
io.Writer type is an interface, and the
http.ResponseWriter object satisfies the interface because it has a
If you’re new to Go, then the concept of interfaces can be a bit confusing and I don’t want to get too hung up on it right now. It’s enough to know that — in practice — anywhere you see an
io.Writer parameter it’s OK to pass in your
http.ResponseWriter object. Whatever is being written will subsequently be sent as the body of the HTTP response.