How do you handle HTTP server caching in Go?
Example
package main
import (
"net/http"
"time"
)
func main() {
// Create a new HTTP server with a caching middleware
cacheHandler := CacheHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Write the response body
w.Write([]byte("Hello, World!"))
}))
http.ListenAndServe(":8080", cacheHandler)
}
// CacheHandler is a middleware that sets cache headers in the HTTP response.
func CacheHandler(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Set cache headers in the response
w.Header().Set("Cache-Control", "public, max-age=3600")
w.Header().Set("Expires", time.Now().Add(time.Hour).Format(http.TimeFormat))
w.Header().Set("Last-Modified", time.Now().UTC().Format(http.TimeFormat))
// Call the next handler in the chain
next.ServeHTTP(w, r)
})
}
In this example, we create a new HTTP server with a caching middleware that sets the Cache-Control, Expires, and Last-Modified headers in the HTTP response. We then use the http.ListenAndServe function to start the HTTP server with the caching middleware.
You can modify the cache headers in the middleware to suit your caching requirements. Additionally, you can use a caching middleware library such as github.com/patrickmn/go-cache to implement more advanced caching strategies such as in-memory caching or distributed caching. The go-cache library provides an easy-to-use API for storing and retrieving cached data with configurable TTLs and eviction policies.
Example
package main
import (
"fmt"
"net/http"
"time"
"github.com/gregjones/httpcache"
"github.com/gregjones/httpcache/diskcache"
)
func main() {
// Create a new disk cache with a maximum size of 100MB and a TTL of 1 hour
cache := diskcache.New("cache")
cache.MaxSize(100 * 1024 * 1024)
cache.TTL(time.Hour)
// Create a new HTTP transport with caching enabled
transport := httpcache.NewTransport(cache)
client := &http.Client{Transport: transport}
// Create a new HTTP server with a cache middleware
cacheHandler := CacheHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Send the HTTP request to the origin server using the caching HTTP client
res, err := client.Do(r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer res.Body.Close()
// Copy the response headers and body to the HTTP response
for key, values := range res.Header {
for _, value := range values {
w.Header().Add(key, value)
}
}
w.WriteHeader(res.StatusCode)
_, _ = w.Write([]byte("Cached response: "))
// Write the response body to the HTTP response
_, _ = io.Copy(w, res.Body)
}))
http.ListenAndServe(":8080", cacheHandler)
}
// CacheHandler is a middleware that sets cache headers in the HTTP response.
func CacheHandler(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Set cache headers in the response
w.Header().Set("Cache-Control", "public, max-age=3600")
w.Header().Set("Expires", time.Now().Add(time.Hour).Format(http.TimeFormat))
w.Header().Set("Last-Modified", time.Now().UTC().Format(http.TimeFormat))
// Call the next handler in the chain
next.ServeHTTP(w, r)
})
}
In this example, we first create a new disk cache with a maximum size of 100MB and a TTL of 1 hour using the diskcache.New function from the httpcache/diskcache package. We then create a new HTTP transport with caching enabled using the httpcache.NewTransport function from the httpcache package, and we use this transport to create a new HTTP client.
Next, we create a new HTTP server with a caching middleware that intercepts incoming requests and outgoing responses. In the middleware, we use the caching HTTP client to send the HTTP request to the origin server and retrieve the HTTP response. We then copy the response headers and body to the HTTP response for the client. If the response is already cached, the middleware will write a "Cached response: " message to the HTTP response before writing the cached content.
Finally, we set cache headers in the HTTP response using the CacheHandler middleware. The middleware sets the Cache-Control, Expires, and Last-Modified headers in the HTTP response to indicate that the response can be cached by the client.
Note that this is just an example and you may need to modify the cache headers and caching strategies to suit your application's needs. Additionally, you may want to use a different caching library or caching strategy depending on your requirements.