Documentation Index
Fetch the complete documentation index at: https://mintlify.com/gofiber/fiber/llms.txt
Use this file to discover all available pages before exploring further.
ETag middleware for Fiber that helps caches validate responses and saves bandwidth by avoiding full retransmits when content is unchanged.
Signatures
func New(config ...Config) fiber.Handler
Usage
import (
"github.com/gofiber/fiber/v3"
"github.com/gofiber/fiber/v3/middleware/etag"
)
Basic Example
// Initialize default config
app.Use(etag.New())
// GET / -> ETag: "13-1831710635"
app.Get("/", func(c fiber.Ctx) error {
return c.SendString("Hello, World!")
})
// Or extend your config for customization
app.Use(etag.New(etag.Config{
Weak: true,
}))
// GET / -> ETag: W/"13-1831710635"
app.Get("/", func(c fiber.Ctx) error {
return c.SendString("Hello, World!")
})
Entity tags in requests must be quoted per RFC 9110. For example:If-None-Match: "example-etag"
Configuration
Next
func(fiber.Ctx) bool
default:"nil"
Defines a function to skip this middleware when it returns true.
Enables weak validators. Weak ETags are easier to generate but less reliable for comparisons. Weak ETags are prefixed with W/.
Default Config
var ConfigDefault = Config{
Next: nil,
Weak: false,
}
How It Works
The ETag middleware generates a unique hash based on the response body:
- Strong ETags (default): Used for byte-for-byte identical content
- Weak ETags: Indicated by
W/ prefix, used when content is semantically equivalent but not byte-identical
When a client sends an If-None-Match header with a matching ETag, the server returns 304 Not Modified instead of the full response body, saving bandwidth.
Common Use Cases
API Response Caching
app.Use(etag.New())
app.Get("/api/users", func(c fiber.Ctx) error {
users := getUsersFromDB()
return c.JSON(users)
})
Static Content with Strong ETags
app.Use("/static", etag.New(etag.Config{
Weak: false, // Strong ETags for exact matching
}))
app.Static("/static", "./public")
Dynamic Content with Weak ETags
app.Use("/pages", etag.New(etag.Config{
Weak: true, // Content may vary slightly
}))
app.Get("/pages/:id", func(c fiber.Ctx) error {
page := getPageContent(c.Params("id"))
return c.SendString(page)
})
Selective ETag Usage
app.Use(etag.New(etag.Config{
Next: func(c fiber.Ctx) bool {
// Skip ETag for certain paths
return c.Path() == "/api/realtime" ||
c.Path() == "/health"
},
}))
Combining with Cache Middleware
import (
"github.com/gofiber/fiber/v3/middleware/cache"
"github.com/gofiber/fiber/v3/middleware/etag"
)
// Apply both middlewares
app.Use(etag.New())
app.Use(cache.New(cache.Config{
Expiration: 5 * time.Minute,
}))
Client Usage
# First request - get ETag
curl -i http://localhost:3000/api/data
# Response includes: ETag: "abc123"
# Subsequent request - send If-None-Match
curl -i http://localhost:3000/api/data -H 'If-None-Match: "abc123"'
# Response: 304 Not Modified (if content unchanged)
JavaScript Fetch API
let etag = null;
async function fetchData() {
const headers = {};
if (etag) {
headers['If-None-Match'] = etag;
}
const response = await fetch('/api/data', { headers });
if (response.status === 304) {
console.log('Using cached data');
return cachedData;
}
etag = response.headers.get('ETag');
const data = await response.json();
cachedData = data;
return data;
}
- Reduced Bandwidth: 304 responses have no body, saving transfer costs
- Faster Response Times: Smaller responses mean quicker page loads
- Server Load Reduction: Less data processing and transmission
- CDN Optimization: Better cache hit rates with proper ETag usage