# Cache et ETag

> Cache-Control, ETag et 304 Not Modified : économisez vos requêtes et vos quotas.

Documentation de l’API de WoWDB des Défias : https://docs.wowdb.assemblee-defias.fr/cache

## Cache-Control

Les réponses réussies portent `Cache-Control: public, max-age=600, stale-while-revalidate=86400` : gardez-les 10 minutes sans redemander, puis revalidez. Les données ne changent qu’aux mises à jour de WoWDB ; la date des données est dans `data_updated` (racine de l’API) et `updated_at` (`/stats`).

Les erreurs ne se gardent pas (`no-store`), sauf les `404`, une minute.

## ETag et If-None-Match

Chaque réponse `200` a un `ETag`, l’empreinte de son contenu. Renvoyez-le dans `If-None-Match` : si rien n’a changé, la réponse est `304 Not Modified`, sans corps. C’est plus rapide, plus léger, et votre copie locale reste valable.

`If-None-Match` accepte plusieurs ETag séparés par des virgules, et la forme faible `W/"…"` que posent certains intermédiaires.

**Requête conditionnelle**

#### cURL

```bash
# Première requête : notez l'ETag.
curl -si https://api.wowdb.assemblee-defias.fr/v1/classic/items/5191 | grep -i etag
# ETag: "…"

# Ensuite : 304 Not Modified, sans corps, tant que la fiche n'a pas changé.
curl -si https://api.wowdb.assemblee-defias.fr/v1/classic/items/5191 \
  -H 'If-None-Match: "…"'
```

#### JavaScript

```js
// Cache en mémoire par ETag : une requête conditionnelle, puis la copie locale si 304.
const cache = new Map();
async function getEnCache(url) {
  const copie = cache.get(url);
  const res = await fetch(url, { headers: copie ? { "If-None-Match": copie.etag } : {} });
  if (res.status === 304) return copie.data;
  const data = await res.json();
  cache.set(url, { etag: res.headers.get("ETag"), data });
  return data;
}
```

#### Python

```python
import json
import urllib.error
import urllib.request

cache = {}

def get_en_cache(url):
    """Requête conditionnelle : la copie locale si la fiche n'a pas changé (304)."""
    copie = cache.get(url)
    req = urllib.request.Request(url, headers={"If-None-Match": copie[0]} if copie else {})
    try:
        with urllib.request.urlopen(req) as res:
            data = json.load(res)
            cache[url] = (res.headers["ETag"], data)
            return data
    except urllib.error.HTTPError as e:
        if e.code == 304:
            return copie[1]
        raise
```

---

API de WoWDB des Défias, v1 (2026-10-01). Adresse de base : https://api.wowdb.assemblee-defias.fr/v1. Index : https://docs.wowdb.assemblee-defias.fr/llms.txt.
