Quickback Docs

Caching & ETags

Automatic ETag-based caching for GET, LIST, and VIEW responses.

Quickback APIs include automatic ETag support on all read endpoints. This lets clients and edge caches avoid re-transferring unchanged data, reducing latency and bandwidth.

How it works

  1. Every GET, LIST, and VIEW response includes a weak ETag header computed from the JSON body:

    ETag: W/"a1b2c3d4e5f60718"
  2. On subsequent requests, the client sends the ETag back:

    If-None-Match: W/"a1b2c3d4e5f60718"
  3. If the data hasn't changed, the server returns 304 Not Modified with no body — saving bandwidth and parse time.

  4. If the data has changed, the server returns the full response with a new ETag.

Which endpoints support ETags

EndpointETagNotes
GET / (list)Yes
GET /:id (get)Yes
GET /views/:name (view)Yes
POST / (create)NoMutations don't cache
PUT /:id (update)No
DELETE /:id (delete)No
ActionsNoSide-effectful
Batch operationsNoMutations

Security

ETags are computed after all security pillars are applied (Firewall, Access, Guards, Masking). This means:

  • Different users with different masking rules get different ETags
  • Firewall-scoped data produces ETags specific to that scope
  • There is no risk of leaking data across users via cached ETags

Response headers

When ETags are enabled, GET responses include:

Content-Type: application/json
ETag: W/"a1b2c3d4e5f60718"
Cache-Control: no-cache

Cache-Control: no-cache means the browser (or edge cache) must revalidate on every request, but can use the cached response if the ETag matches. This is the correct behavior for authenticated APIs — data is always fresh, but unchanged responses avoid re-transfer.

Client usage

fetch API

// First request
const res = await fetch("/api/v1/jobs");
const etag = res.headers.get("ETag");
const data = await res.json();

// Subsequent request with ETag
const res2 = await fetch("/api/v1/jobs", {
  headers: { "If-None-Match": etag },
});

if (res2.status === 304) {
  // Data hasn't changed, use cached version
} else {
  const freshData = await res2.json();
}

Axios / ky / other clients

Most HTTP clients handle 304 responses automatically when configured with an interceptor or cache adapter.

Configuration

ETags are enabled by default. To disable them, set etag.enabled to false in quickback.config.ts:

export default defineConfig({
  name: "my-app",
  // ...
  etag: {
    enabled: false,
  },
});

When disabled, GET responses use standard c.json() with no ETag headers or 304 handling.

OptionDefaultDescription
enabledtrueInclude ETag headers on GET/LIST/VIEW responses

Technical details

  • Weak ETags (W/"...") — semantically equivalent responses, not byte-identical
  • SHA-256 truncated to 16 hex chars — sufficient for collision avoidance, keeps the header small
  • Web Crypto API — uses crypto.subtle.digest(), available in Cloudflare Workers and Node 18+
  • No dependencies — zero additional packages required

On this page