Documentation Index
Fetch the complete documentation index at: https://docs.go-mizu.dev/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The cache middleware sets Cache-Control headers to control HTTP caching behavior. It helps optimize performance by instructing browsers and CDNs how to cache responses.
Installation
import "github.com/go-mizu/mizu/middlewares/cache"
Quick Start
app := mizu.New()
// Cache for 1 hour
app.Use(cache.New(time.Hour))
Configuration
| Option | Type | Description |
|---|
MaxAge | time.Duration | Browser cache duration |
SMaxAge | time.Duration | CDN/proxy cache duration |
Public | bool | Allow public caching |
Private | bool | Restrict to browser only |
NoCache | bool | Require revalidation |
NoStore | bool | Don’t cache at all |
NoTransform | bool | Prevent transformations |
MustRevalidate | bool | Must check freshness |
Immutable | bool | Content never changes |
StaleWhileRevalidate | time.Duration | Serve stale while fetching |
StaleIfError | time.Duration | Serve stale on errors |
Examples
Basic Caching
// Cache for 1 hour
app.Use(cache.New(time.Hour))
Public Cache (CDN)
// Allow CDN caching
app.Get("/static/*", staticHandler, cache.Public(24*time.Hour))
Private Cache (Browser Only)
// User-specific data, browser only
app.Get("/profile", profileHandler, cache.Private(time.Hour))
Immutable Assets
// Never changes (versioned assets)
app.Get("/assets/*", assetHandler, cache.Immutable(365*24*time.Hour))
Stale-While-Revalidate
// Serve stale for 1 hour while revalidating
app.Get("/api/feed", feedHandler, cache.SWR(time.Minute, time.Hour))
Full Configuration
app.Use(cache.WithOptions(cache.Options{
MaxAge: time.Hour,
SMaxAge: 24 * time.Hour,
Public: true,
MustRevalidate: true,
StaleWhileRevalidate: 10 * time.Minute,
}))
Different Cache Strategies
// API: Short cache with revalidation
api := app.Group("/api")
api.Use(cache.SWR(time.Minute, 5*time.Minute))
// Static: Long cache, immutable
static := app.Group("/static")
static.Use(cache.Immutable(365*24*time.Hour))
// Private data: Browser only
private := app.Group("/user")
private.Use(cache.Private(5*time.Minute))
API Reference
func New(maxAge time.Duration) mizu.Middleware
func WithOptions(opts Options) mizu.Middleware
func Public(maxAge time.Duration) mizu.Middleware
func Private(maxAge time.Duration) mizu.Middleware
func Immutable(maxAge time.Duration) mizu.Middleware
func Static(maxAge time.Duration) mizu.Middleware
func SWR(maxAge, stale time.Duration) mizu.Middleware
Common Patterns
| Use Case | Directive |
|---|
| Static files | public, max-age=31536000, immutable |
| API responses | private, max-age=60 |
| CDN cached | public, s-maxage=86400, max-age=60 |
| User data | private, no-cache |
| Never cache | no-store |
Technical Details
Implementation
The cache middleware operates by constructing and setting the Cache-Control HTTP header based on the provided configuration options. The middleware:
- Header Construction: Uses the
buildCacheControl function to build the Cache-Control header string from the Options struct
- Non-Overriding Behavior: Only sets the Cache-Control header if it hasn’t been set by the handler or previous middleware
- Default Fallback: Returns
no-cache when no options are specified
- Time Conversion: Converts Go
time.Duration values to seconds for cache directives (max-age, s-maxage, etc.)
Cache-Control Directives
The middleware supports the following HTTP Cache-Control directives:
- public: Response may be cached by any cache (browsers, CDNs, proxies)
- private: Response is intended for a single user and should only be cached by the browser
- no-cache: Cache must revalidate with the origin server before using cached content
- no-store: Response must not be stored in any cache
- no-transform: Intermediaries must not transform the response (e.g., image compression)
- must-revalidate: Cache must verify the status of stale resources and expired ones should not be used
- proxy-revalidate: Same as must-revalidate but only for shared caches
- max-age=N: Maximum time (in seconds) a resource is considered fresh
- s-maxage=N: Overrides max-age for shared caches (CDNs, proxies)
- immutable: Resource will never change during its freshness lifetime
- stale-while-revalidate=N: Cache may serve stale content while revalidating in the background
- stale-if-error=N: Cache may serve stale content if an error occurs during revalidation
Helper Functions
The package provides several convenience functions that configure common caching strategies:
- New(maxAge): Basic caching with max-age
- Public(maxAge): Public caching with max-age
- Private(maxAge): Private caching with max-age
- Immutable(maxAge): Immutable public content with max-age
- Static(maxAge): Alias for Immutable, suitable for static assets
- SWR(maxAge, stale): Stale-while-revalidate pattern for improved perceived performance
Best Practices
- Use appropriate cache strategies for different content types
- Leverage stale-while-revalidate for improved user experience
- Set immutable for versioned static assets
- Use private for user-specific data
- Combine with CDN using s-maxage for better edge caching
Testing
The cache middleware includes comprehensive test coverage for all functionality:
| Test Case | Description | Expected Behavior |
|---|
| TestNew | Basic middleware creation with max-age | Sets Cache-Control header with max-age=3600 for 1 hour duration |
| TestWithOptions - public with max-age | Public cache with max-age | Contains “public” and “max-age=3600” directives |
| TestWithOptions - private with max-age | Private cache with max-age | Contains “private” and “max-age=300” directives |
| TestWithOptions - no-cache | No-cache directive | Contains “no-cache” directive |
| TestWithOptions - no-store | No-store directive | Contains “no-store” directive |
| TestWithOptions - must-revalidate | Must-revalidate with max-age | Contains “must-revalidate” and “max-age=3600” directives |
| TestWithOptions - immutable | Immutable content | Contains “public” and “immutable” directives |
| TestWithOptions - s-maxage | Shared cache max-age | Contains “max-age=3600” and “s-maxage=7200” directives |
| TestWithOptions - stale-while-revalidate | Stale-while-revalidate pattern | Contains “max-age=3600” and “stale-while-revalidate=1800” directives |
| TestPublic | Public cache helper function | Cache-Control header contains “public” directive |
| TestPrivate | Private cache helper function | Cache-Control header contains “private” directive |
| TestImmutable | Immutable cache helper function | Cache-Control header contains “immutable” directive |
| TestStatic | Static assets cache helper function | Cache-Control header contains “public” and “immutable” directives |
| TestSWR | Stale-while-revalidate helper function | Cache-Control header contains “stale-while-revalidate=1800” directive |
| TestWithOptions_DoesNotOverride | Existing Cache-Control header preservation | Middleware does not override pre-existing Cache-Control headers |
| TestWithOptions_Empty | Empty options handling | Defaults to “no-cache” when no options are provided |
Security Considerations
- Sensitive data: Always use
private or no-store for sensitive information
- User-specific content: Never use
public for personalized data
- Authentication: Consider using
no-cache or no-store for authenticated routes