Today i was having a problem with my web api in Go. A lot of my API’s are cached by the browser because the Expires time of the response was automatically set to 4 days than the first request.

The expires time was a header information from the response, if you are not familiar with this. You can use

curl -XGET -i http://url/api/endpoint

Or you can use the network inspector on modern web browser such as Google Chrome or Firefox and other.

Above is one of the examples of using curl.

As you can see on the image above, the expires time is set to epoch time.

If you are not familiar enough what is it epoch time, you can read http://en.wikipedia.org/wiki/Unix_time#History.

Let’s jump to the reason why i set my expires time to epoch time.

As i mention before, i was having a problem with my web api. A lot of request was cached by the browser and cause a bad user experience.

I use XHR (XML Http Request) for every reqeust on my web application, that’s why a lot of request was easily cached by the browser, because the response tells the browser that this api is expired in 4 days.

There are a lot of ways to resolve this thing actually, and this is the simplest method to resolve this kind of problem.

Simple but it doesn’t mean the best way to solve this. If you are using this, you may have to considered that a few of your web api is needed to be cached by the browser.

And thankfully, Go is implement http handler very good. So i can set my web api separately, i can do such grouping my web api. And of course, the best thing ever is that i can implement any middleware to any route, or any group.

So, for an example i have this route:

  • /api/v1/:resource_model:
  • /api/v1/session

I can easily write a middleware to set the header and set expires time to epoch for every route that i wanted to be set as always expired.

Since i was using Gin as my web framework, so this is my middleware.

func EpochExpires() gin.HandlerFunc {
	return func(c *gin.Context) {
		c.Writer.Header().Set("Expires", "Thu, 1 Jan 1970 00:00:00 GMT")
		c.Next()
	}
}

But of course, because it is only set the http.ResponseWriter Header. You can write your own middleware for any web framework, or not using framework at all. Because this method could be implemented on native net/http handler.