Pagination
Listen der Developer-API kommen seitenweise. Du blätterst mit einem Cursor, nicht mit Seitenzahlen.
Parameter
limitlegt fest, wie viele Einträge eine Seite hat: 1 bis 100, Standard 25.cursorruft die nächste Seite ab. Du nimmst ihn aus der vorigen Antwort. Für die erste Seite lässt du ihn weg.
Der Cursor ist ein undurchsichtiger Text. Lies ihn nicht aus, baue keinen selbst und ändere ihn nicht. Ein ungültiger Cursor oder ein limit außerhalb von 1 bis 100 liefert 400 VALIDATION_ERROR.
Antwort
Jede Liste antwortet mit { data, nextCursor }. data enthält die Einträge der Seite. nextCursor ist der Cursor für die nächste Seite. Ist er null, gibt es keine weitere Seite. Das gilt für alle Listen außer dem Ereignis-Feed GET /events, siehe unten.
{
"data": [
{ "id": "…", "name": "Survival", "status": "ready" }
],
"nextCursor": "x7Kq2mWv9Rt4ZaPb1LcHf8Ns"
}Alle Seiten abrufen
Rufe so lange die nächste Seite ab, bis nextCursornull ist.
# erste Seite curl "https://api.zenit-hosting.de/api/developer/v1/servers?limit=50" \ -H "Authorization: Bearer $ZENIT_TOKEN" # nächste Seite: nextCursor der letzten Antwort als cursor curl "https://api.zenit-hosting.de/api/developer/v1/servers?limit=50&cursor=$NEXT_CURSOR" \ -H "Authorization: Bearer $ZENIT_TOKEN"
const BASE = 'https://api.zenit-hosting.de/api/developer/v1';
async function listAllServers() {
const servers = [];
let cursor = null;
do {
const url = new URL(BASE + '/servers');
url.searchParams.set('limit', '100');
if (cursor) url.searchParams.set('cursor', cursor);
const response = await fetch(url, {
headers: { Authorization: 'Bearer ' + process.env.ZENIT_TOKEN },
});
if (!response.ok) throw new Error('HTTP ' + response.status);
const page = await response.json();
servers.push(...page.data);
cursor = page.nextCursor;
} while (cursor);
return servers;
}import os
import requests
BASE = "https://api.zenit-hosting.de/api/developer/v1"
def list_all_servers():
servers = []
cursor = None
while True:
params = {"limit": 100}
if cursor:
params["cursor"] = cursor
response = requests.get(
BASE + "/servers",
params=params,
headers={"Authorization": "Bearer " + os.environ["ZENIT_TOKEN"]},
timeout=10,
)
response.raise_for_status()
page = response.json()
servers.extend(page["data"])
cursor = page["nextCursor"]
if not cursor:
return serversSonderfälle
GET /servers/{id}/backupsantwortet mitdata,nextCursorundlimit.nextCursorist dort immernull, es gibt keine weitere Seite abzurufen.
Ereignis-Feed: nextCursor bedeutet etwas anderes
GET /events?after= ist kein Blättern durch eine Liste, sondern ein Feed, den du fortlaufend abfragst. Er blättert mit after statt mit cursor und gilt nur für Bot-Tokens.
nextCursorist im Feed immer die Position nach dem zuletzt gelesenen Ereignis. Kam nichts Neues, ist es derafter, den du übergeben hast.- Eine leere
dataheißt: Du bist auf dem neuesten Stand. Warte kurz und frage mit demselbennextCursorerneut. nullistnextCursornur, wenn du ohneafterfragst und es noch kein Ereignis gibt. Es heißt im Feed nie „keine weitere Seite“.- Speichere den gelieferten
nextCursordauerhaft, sofern er nichtnullist.
Ein Beispiel steht unter Bots und Manifest.
