Pagination
Die MILKEE API verwendet Pagination für Listen-Endpoints, um die Performance zu optimieren und die Übertragung grosser Datenmengen zu vermeiden.
Resource Collections
Listen-Endpoints geben Resource Collections im folgenden Format zurück:
json
{
"data": [
{
"id": 1,
"name": "reisekosten",
"color": "blue",
"company_id": 123,
"user_id": 456
},
{
"id": 2,
"name": "büromaterial",
"color": "green",
"company_id": 123,
"user_id": 456
}
],
"links": {
"first": "https://app.milkee.ch/api/v2/companies/123/tags?page=1",
"last": "https://app.milkee.ch/api/v2/companies/123/tags?page=5",
"prev": null,
"next": "https://app.milkee.ch/api/v2/companies/123/tags?page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 5,
"path": "https://app.milkee.ch/api/v2/companies/123/tags",
"per_page": 15,
"to": 15,
"total": 67
}
}
Pagination-Parameter
Standard-Parameter
Parameter | Typ | Standard | Beschreibung |
---|---|---|---|
page | integer | 1 | Seitennummer (1-basiert) |
per_page | integer | 15 | Anzahl Elemente pro Seite |
Limits
- Minimum
per_page
: 1 - Maximum
per_page
: 100 - Standard
per_page
: 15
Pagination verwenden
Erste Seite abrufen
bash
curl -H "Authorization: Bearer abcdef123456789..." \
"https://app.milkee.ch/api/v2/companies/123/tags"
Spezifische Seite abrufen
bash
curl -H "Authorization: Bearer abcdef123456789..." \
"https://app.milkee.ch/api/v2/companies/123/tags?page=3"
Anzahl Elemente pro Seite anpassen
bash
curl -H "Authorization: Bearer abcdef123456789..." \
"https://app.milkee.ch/api/v2/companies/123/tags?per_page=50"
Kombinierte Parameter
bash
curl -H "Authorization: Bearer abcdef123456789..." \
"https://app.milkee.ch/api/v2/companies/123/tags?page=2&per_page=25"
Response-Struktur
data-Array
Das data
-Array enthält die aktuellen Ressourcen für die angeforderte Seite.
links-Objekt
Feld | Beschreibung |
---|---|
first | URL zur ersten Seite |
last | URL zur letzten Seite |
prev | URL zur vorherigen Seite (null bei erster Seite) |
next | URL zur nächsten Seite (null bei letzter Seite) |
meta-Objekt
Feld | Beschreibung |
---|---|
current_page | Aktuelle Seitennummer |
from | Index des ersten Elements auf dieser Seite |
last_page | Nummer der letzten Seite |
path | Base-URL ohne Query-Parameter |
per_page | Anzahl Elemente pro Seite |
to | Index des letzten Elements auf dieser Seite |
total | Gesamtanzahl Elemente |
Pagination in Code
JavaScript/Fetch
javascript
async function getAllTags(companyId, token) {
let allTags = [];
let currentPage = 1;
let hasMorePages = true;
while (hasMorePages) {
const response = await fetch(
`https://app.milkee.ch/api/v2/companies/${companyId}/tags?page=${currentPage}`,
{
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
}
);
const data = await response.json();
allTags = allTags.concat(data.data);
// Prüfen ob weitere Seiten vorhanden
hasMorePages = data.meta.current_page < data.meta.last_page;
currentPage++;
}
return allTags;
}
// Oder mit async iterator
async function* paginateTagsIterator(companyId, token, perPage = 15) {
let currentPage = 1;
let hasMorePages = true;
while (hasMorePages) {
const response = await fetch(
`https://app.milkee.ch/api/v2/companies/${companyId}/tags?page=${currentPage}&per_page=${perPage}`,
{
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
}
);
const data = await response.json();
yield data.data;
hasMorePages = data.meta.current_page < data.meta.last_page;
currentPage++;
}
}
// Verwendung des Iterators
for await (const tagBatch of paginateTagsIterator(123, token, 50)) {
console.log(`Verarbeite ${tagBatch.length} Tags`);
// Verarbeitung der Tags...
}
PHP
php
<?php
function getAllTags($companyId, $token) {
$allTags = [];
$currentPage = 1;
$hasMorePages = true;
while ($hasMorePages) {
$url = "https://app.milkee.ch/api/v2/companies/{$companyId}/tags?page={$currentPage}";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $token,
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
$allTags = array_merge($allTags, $data['data']);
$hasMorePages = $data['meta']['current_page'] < $data['meta']['last_page'];
$currentPage++;
}
return $allTags;
}
// Generator für speicherschonende Verarbeitung
function paginateTags($companyId, $token, $perPage = 15) {
$currentPage = 1;
$hasMorePages = true;
while ($hasMorePages) {
$url = "https://app.milkee.ch/api/v2/companies/{$companyId}/tags?page={$currentPage}&per_page={$perPage}";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $token,
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
yield $data['data'];
$hasMorePages = $data['meta']['current_page'] < $data['meta']['last_page'];
$currentPage++;
}
}
// Verwendung
foreach (paginateTags(123, $token, 50) as $tagBatch) {
echo "Verarbeite " . count($tagBatch) . " Tags\n";
// Verarbeitung der Tags...
}
Performance-Tipps
Optimale Page-Size wählen
- Kleine per_page (1-15): Schnelle Antwortzeiten, mehr Requests nötig
- Mittlere per_page (16-50): Ausgewogenes Verhältnis von Speed und Datenmenge
- Grosse per_page (51-100): Weniger Requests, langsamere Antwortzeiten
Caching implementieren
javascript
class PaginatedCache {
constructor(ttl = 5 * 60 * 1000) { // 5 Minuten TTL
this.cache = new Map();
this.ttl = ttl;
}
getCacheKey(endpoint, page, perPage) {
return `${endpoint}?page=${page}&per_page=${perPage}`;
}
get(endpoint, page, perPage) {
const key = this.getCacheKey(endpoint, page, perPage);
const cached = this.cache.get(key);
if (!cached) return null;
if (Date.now() - cached.timestamp > this.ttl) {
this.cache.delete(key);
return null;
}
return cached.data;
}
set(endpoint, page, perPage, data) {
const key = this.getCacheKey(endpoint, page, perPage);
this.cache.set(key, {
data,
timestamp: Date.now()
});
}
}
Prefetching
javascript
async function prefetchNextPage(companyId, currentPage, token) {
// Nächste Seite im Hintergrund laden
setTimeout(async () => {
try {
await fetch(
`https://app.milkee.ch/api/v2/companies/${companyId}/tags?page=${currentPage + 1}`,
{
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
}
);
} catch (error) {
// Prefetch-Fehler ignorieren
}
}, 100);
}