Serving JSON in Go with http.ServeContent
I know many will start with something like Gin whenever they are working on a JSON/HTTP-based backend in Go.
I, not entirely sure if the minority, try to stick to Go’s built-in net/http
package and, at most, use Gorilla Mux in most of my Go projects.
And so serving something simple like JSON is no different from the package’s point of view as any other content type: whatever it is, write it out to the w
, the http.ResponseWriter
.
But that means there are a few things worth remembering when serving JSON responses in Go over HTTP. And I am going to go over a few in this blog post.
The Basic
|
|
The serveMessage
handler function uses the json.NewEncoder
function to create a new encoder around w
and encode the message.
You can expect the response body to look like this (minus indentations, line breaks and spaces):
{
"text": "Hello world",
"ts": "2023-11-14T10:00:00Z"
}
But is that all?
Content-Type Header
If you are serving JSON, you should set the Content-Type
header to “application/json”:
|
|
What if we want the browser to cache the response?
Last-Modified Header
It is where the http.ServeContent
function becomes useful.
|
|
The http.ServeContent
function will automatically add the Last-Modified
header to the response.
It will also check for the If-Modified-Since
header in the request body. If present, and if it is not older than the time.Time
passed as the modtime
argument, the response may not include the content (and have the status 304 Not Modified
instead).
The exact headers you want to use depend on how you want the responses cached by the web browser. The example above will cause the browser to revalidate the request every time.
If the timestamp in the TS
field doesn’t change, the web browser will not have to redownload the response body.
ETag Header
The http.ServeContent
function also handles If-Match
, If-None-Match
, or If-Range
headers. These work if you set the ETag
header in your response:
|
|
We are generating a weak entity tag here by concatenating the length and hash of the JSON response payload.
What Else
What else should one keep in mind when serving JSON responses in Go? Let me know if I missed something.
This post is 92nd of my #100DaysToOffload challenge. Want to get involved? Find out more at 100daystooffload.com.
comments powered by Disqus