docs(api): align cache docs with explicit limits
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
5e4cf1fde8
commit
4725b39049
2 changed files with 39 additions and 3 deletions
|
|
@ -106,6 +106,36 @@ func TestWithCache_Good_CachesGETResponse(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestWithCacheLimits_Good_CachesGETResponse(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
grp := &cacheCounterGroup{}
|
||||
e, _ := api.New(api.WithCacheLimits(5*time.Second, 1, 0))
|
||||
e.Register(grp)
|
||||
|
||||
h := e.Handler()
|
||||
|
||||
w1 := httptest.NewRecorder()
|
||||
req1, _ := http.NewRequest(http.MethodGet, "/cache/counter", nil)
|
||||
h.ServeHTTP(w1, req1)
|
||||
if w1.Code != http.StatusOK {
|
||||
t.Fatalf("expected 200, got %d", w1.Code)
|
||||
}
|
||||
|
||||
w2 := httptest.NewRecorder()
|
||||
req2, _ := http.NewRequest(http.MethodGet, "/cache/counter", nil)
|
||||
h.ServeHTTP(w2, req2)
|
||||
if w2.Code != http.StatusOK {
|
||||
t.Fatalf("expected 200, got %d", w2.Code)
|
||||
}
|
||||
|
||||
if got := w2.Header().Get("X-Cache"); got != "HIT" {
|
||||
t.Fatalf("expected X-Cache=HIT, got %q", got)
|
||||
}
|
||||
if grp.counter.Load() != 1 {
|
||||
t.Fatalf("expected counter=1 (cached), got %d", grp.counter.Load())
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithCache_Good_POSTNotCached(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
grp := &cacheCounterGroup{}
|
||||
|
|
|
|||
|
|
@ -176,7 +176,8 @@ They execute after `gin.Recovery()` but before any route handler. The `Option` t
|
|||
| `WithBrotli(level...)` | Brotli response compression | Writer pool for efficiency; default compression if level omitted |
|
||||
| `WithSlog(logger)` | Structured request logging | Falls back to `slog.Default()` if nil |
|
||||
| `WithTimeout(d)` | Per-request deadline | 504 with standard error envelope on timeout |
|
||||
| `WithCache(ttl)` | In-memory GET response caching | `X-Cache: HIT` header on cache hits; 2xx only |
|
||||
| `WithCache(ttl)` | In-memory GET response caching | Compatibility wrapper for `WithCacheLimits(ttl, 0, 0)`; `X-Cache: HIT` header on cache hits; 2xx only |
|
||||
| `WithCacheLimits(ttl, maxEntries, maxBytes)` | In-memory GET response caching with explicit bounds | Clearer cache configuration when eviction policy should be self-documenting |
|
||||
| `WithSessions(name, secret)` | Cookie-backed server sessions | gin-contrib/sessions with cookie store |
|
||||
| `WithAuthz(enforcer)` | Casbin policy-based authorisation | Subject from HTTP Basic Auth; 403 on deny |
|
||||
| `WithHTTPSign(secrets, opts...)` | HTTP Signatures verification | draft-cavage-http-signatures; 401/400 on failure |
|
||||
|
|
@ -383,14 +384,19 @@ redirects and introspection). The GraphQL handler is created via gqlgen's
|
|||
|
||||
## 8. Response Caching
|
||||
|
||||
`WithCache(ttl)` installs a URL-keyed in-memory response cache scoped to GET requests:
|
||||
`WithCacheLimits(ttl, maxEntries, maxBytes)` installs a URL-keyed in-memory response cache scoped to GET requests:
|
||||
|
||||
```go
|
||||
engine, _ := api.New(api.WithCacheLimits(5*time.Minute, 100, 10<<20))
|
||||
```
|
||||
|
||||
- Only successful 2xx responses are cached.
|
||||
- Non-GET methods pass through uncached.
|
||||
- Cached responses are served with an `X-Cache: HIT` header.
|
||||
- Expired entries are evicted lazily on the next access for the same key.
|
||||
- The cache is not shared across `Engine` instances.
|
||||
- There is no size limit on the cache.
|
||||
- `WithCache(ttl)` remains available as a compatibility wrapper for callers that do not need to spell out the bounds.
|
||||
- Passing non-positive values to `WithCacheLimits` leaves that limit unbounded.
|
||||
|
||||
The implementation uses a `cacheWriter` that wraps `gin.ResponseWriter` to intercept and
|
||||
capture the response body and status code for storage.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue