Paginering med side og per_side
Hent lange lister side for side med side og per_side, kend grænserne pr. endpoint, og skriv en løkke, der stopper ved den sidste side.
Lister som /adresser, /vejnavne og /postnumre returnerer resultatet i sider. Du vælger siden med side og størrelsen med per_side, præcis som i DAWA. Hver side er et API-kald, så færre og større sider er billigere end mange små.
Parametrene
sideer sidenummeret. Den første side er1.side=0giver en valideringsfejl.per_sideer antal rækker pr. side. Standarden er 100 på de fleste lister. Se tabellen for, hvad du får uden de to parametre.
curl -s "https://api.danadresse.dk/adresser?postnr=8000&side=2&per_side=2" \ -H "X-Api-Key: $DANADRESSE_API_KEY"
Svaret er en almindelig JSON-liste. Der er ingen header eller felt med det samlede antal, og ingen "næste side"-link. Du ved, at du er på den sidste side, når den har færre rækker end per_side.
Grænser pr. endpoint
| Endpoint | Uden side og per_side | per_side maks. | side |
|---|---|---|---|
/adresser, /adgangsadresser | de første 100 | 1000 | ja |
/postnumre, /sogne, /supplerendebynavne, /supplerendebynavne2 | hele listen | 1000 | ja |
/vejnavne, /vejstykker | hele listen med kommunekode eller postnr, ellers de første 100 | 1000 | ja |
/navngivneveje, /ejerlav, /jordstykker, /matrikelnumre, /steder, /stednavne | de første 100 | 1000 | ja |
/kommuner | hele listen | 500 | ja |
/autocomplete | 20 forslag | 100 | nej |
/adresser/autocomplete, /adgangsadresser/autocomplete, /postnumre/autocomplete, /vejnavne/autocomplete, /vejstykker/autocomplete, /ejerlav/autocomplete | 20 forslag | 1000 | nej |
/kommuner/autocomplete | 20 forslag | 500 | nej |
/regioner, /retskredse, /politikredse, /opstillingskredse, /landsdele, /storkredse, /valglandsdele | hele listen | hele listen | nej |
Som i DAWA kommer de små lister hele tilbage, når du ikke sender side eller per_side. /postnumre giver alle postnumre i ét kald, klar til en dropdown. Sender du side eller per_side, er standarden 100 rækker pr. side. På referencelisterne i den sidste række bliver side og per_side ignoreret.
Sætter du per_side højere end grænsen, får du status 400:
{
"type": "QueryParameterFormatError",
"title": "Invalid query parameter",
"details": [
{
"type": "less_than_equal",
"loc": ["query", "per_side"],
"msg": "Input should be less than or equal to 1000",
"input": "5000",
"ctx": {"le": 1000}
}
],
"code": "invalid_query_parameter"
}Løkken: hent indtil en kort side
Opskriften er den samme i alle sprog: start på side 1, hent, og stop når siden har færre rækker end per_side. Går antallet op i per_side, er den sidste side tom, og det koster ét ekstra kald.
En generator i Python, der giver dig rækkerne en ad gangen:
import os from collections.abc import Iterator import requests API = "https://api.danadresse.dk" session = requests.Session() session.headers["X-Api-Key"] = os.environ["DANADRESSE_API_KEY"] def pages(path: str, params: dict | None = None, per_side: int = 1000) -> Iterator[dict]: """Giv alle rækker fra en DAWA-liste, side for side.""" side = 1 while True: r = session.get( API + path, params={**(params or {}), "side": side, "per_side": per_side}, timeout=30, ) r.raise_for_status() rows = r.json() yield from rows if len(rows) < per_side: return side += 1 alle = list(pages("/postnumre")) print(f"Hentede {len(alle)} postnumre. Første: {alle[0]['nr']} {alle[0]['navn']}")
En async iterator i JavaScript til Node 18+. Eksemplet henter alle kommuner i sider på 50:
const API = "https://api.danadresse.dk"; export async function* pages(path, params = {}, perSide = 1000) { for (let side = 1; ; side++) { const url = new URL(API + path); for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v); url.searchParams.set("side", String(side)); url.searchParams.set("per_side", String(perSide)); const res = await fetch(url, { headers: { "X-Api-Key": process.env.DANADRESSE_API_KEY }, }); if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`); const rows = await res.json(); yield* rows; if (rows.length < perSide) return; } } let antal = 0; for await (const kommune of pages("/kommuner", {}, 50)) antal++; console.log(`Hentede ${antal} kommuner`);
Vil du afbryde tidligt, så stop løkken. Generatoren henter kun den næste side, når du beder om flere rækker.
Ting, der er værd at vide
- Rækkefølge. Lister uden
qhar en fast rækkefølge:/adresserog/adgangsadresserefter id, de andre lister efter kode eller navn. På/adresserog/adgangsadresseroverlapper siderne derfor ikke og springer ingen rækker over. Adressedata bliver opdateret løbende, så til et komplet udtræk bruger du replikering. - Fritekst
q. Medqer siderne sorteret efter relevans. Dybe sider giver sjældent mening. Gør søgningen mere præcis i stedet. - Cirkel og polygon. Med
cirkel=ellerpolygon=bliver kandidaterne fundet først og derefter delt i sider, de nærmeste først i en cirkel. Dækker området mere end 50.000 adgangsadresser, får du400med kodenarea_too_largei stedet for et afskåret svar. Gør området mindre, eller tilføjpostnrellerkommunekode. - Hver side er et kald. 2.500 adresser med
per_side=100er 25 kald. Medper_side=1000er det 3. Se Grænser, kvoter og 429.
Når du skal bruge alt: replikering
Paginering er beregnet til lister, som en bruger eller et job har brug for nu: adresserne i et postnummer, vejene i en kommune. Skal du bruge alle Danmarks adresser, så hent dem med /replikering/udtraek?entitet=adresse. Det er én lang JSON-liste i ét kald (eller NDJSON, én række pr. linje, med &ndjson), og bagefter kan du holde dine data opdateret med hændelser. Se Replikering: det første udtræk.
format=ndjson på /adresser giver også NDJSON, men det følger stadig side og per_side. Det er praktisk til at skrive en side direkte til en fil, men det henter ikke hele datasættet.
Næste skridt
Relaterede guides
Markdown-kilde Fejl i guiden? Skriv til os API-reference (Swagger)