Br etag cache
Skill Lonsdale201/wp-agent-skills/better-route/br-etag-cache
A community-maintained collection of agent skills for WordPress plugin and theme development.
npx -y skills add Lonsdale201/wp-agent-skills --skill br-etag-cacheAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 21 stars21 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Add better-route 1.1 ETag and If-None-Match handling to GET or HEAD routes. Use for ETagMiddleware, strong or weak validators, custom etagResolver, WP_REST_Response preservation, comma-separated validators, wildcard matching, 304 responses, Cache-Control, proxy-stripped ETag troubleshooting, or reviewing conditional HTTP caching. The middleware skips WP_Error, 204, redirects, and non-2xx responses.
SKILL.md
4.3 KB, as published. Nobody here has run it
better-route: ETag conditional reads
Use ETags on read routes to let clients revalidate a representation. They do not prevent duplicate writes; use idempotency for that.
use BetterRoute\Middleware\Cache\ETagMiddleware;
$router->get('/catalog', $handler)
->publicRoute()
->middleware([new ETagMiddleware()]);
The default validator is a quoted SHA-1 of the JSON-encoded response body. It applies only to GET/HEAD results with status 200–299 except 204.
1.1 behavior
The middleware preserves Better Route Response and WP_REST_Response status/data. It adds the ETag through the appropriate response API instead of flattening the WordPress response.
It skips:
- returned
WP_Error; - non-2xx responses;
204 No Content;- non-GET/HEAD methods.
If-None-Match accepts:
- a single validator;
- a comma-separated validator list;
- weak or strong forms of the same opaque tag;
*.
On a match, 1.1 returns 304 with no body and preserves cache-relevant source headers: Cache-Control, Content-Location, Expires, and Vary, plus the ETag.
The middleware computes and controls the final ETag header; do not rely on an existing handler ETag remaining unchanged.
Cheap custom validators
For large responses, derive a validator from a stable version instead of hashing the full body:
use BetterRoute\Http\RequestContext;
$etag = new ETagMiddleware(
weak: false,
etagResolver: static function (mixed $response, RequestContext $context): string {
return (string) get_option('myapp_catalog_version', 0);
},
);
Return the opaque value; the middleware quotes it. A returned already-quoted or W/ value is normalized. Invalid quote/control bytes are replaced with a safe hash rather than reaching an HTTP header.
Use weak: true when byte differences may represent the same semantic representation:
new ETagMiddleware(weak: true); // W/"..."
The default JSON hash follows array order. Deeply sort associative data before returning it, or use a stable version resolver, when construction order is nondeterministic.
Cache-Control and privacy
ETag enables revalidation; it does not define freshness or sharing. Set Cache-Control separately:
return new Response($data, 200, [
'Cache-Control' => 'public, max-age=300',
]);
Use private/no-store as appropriate for user-specific data. Never let a shared CDN cache /me or another personalized URL merely because it has an ETag.
Troubleshooting
Test both the public endpoint and the PHP/upstream origin. A reverse proxy, nginx/RunCloud rule, CDN, compression layer, or caching plugin may remove or rewrite an outbound ETag even when application-level matching still produces a correct 304.
Verify:
curl -i 'https://example.com/wp-json/myapp/v1/catalog'
curl -i 'https://example.com/wp-json/myapp/v1/catalog' \
-H 'If-None-Match: "copied-tag"'
Also test If-None-Match: W/"copied-tag", a comma-separated list, and *.
Review checklist
- Attach only to GET/HEAD routes.
- Use a cheap stable resolver for large bodies.
- Set explicit Cache-Control and correct privacy semantics.
- Confirm WP REST response status/data/headers survive.
- Confirm 4xx/5xx and WP_Error do not gain an ETag.
- Confirm matched 304 has no body and retains cache headers.
- Inspect intermediary header behavior if ETag disappears externally.
Related skills
- Use
br-idempotencyorbr-atomic-idempotencyfor write retries. - Use
br-cors-public-clientto exposeETagto browser JavaScript.
References
- Verified source paths:
src/Middleware/Cache/ETagMiddleware.phpsrc/Http/Response.php