From d5e3504f38b3ba05921d97578a5f07d2081208c9 Mon Sep 17 00:00:00 2001 From: Sebastian Poll Date: Thu, 9 Apr 2026 22:02:04 +0000 Subject: [PATCH] auto: 1 file changed, 69 insertions(+) --- DOJO.md | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/DOJO.md b/DOJO.md index fea3b8d..732fdf8 100644 --- a/DOJO.md +++ b/DOJO.md @@ -683,6 +683,74 @@ variation.name; // → '' oder undefined --- +## 29. `/rest/batch`-Endpoint: Mehrere API-Calls in einem Request + +**Lektion:** Der `/rest/batch`-Endpoint ermöglicht bis zu 20 API-Calls in einem HTTP-Request. Das reduziert HTTP-Overhead, aber das **Write-Budget wird trotzdem pro enthaltener Operation gezählt**, nicht pro Batch-Request. + +**Pattern:** +```javascript +const res = await fetch(`${BASE}/rest/batch`, { + method: 'POST', + headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' }, + body: JSON.stringify({ + payloads: items.map(item => ({ + resource: '/rest/properties/relations', // NICHT "uri"! + method: 'POST', + body: { + propertyId: 5, + relationTypeIdentifier: 'item', + relationTargetId: item.varId, + selectionRelationId: 48 + } + })) + }) +}); +// Response: Array von { resource, method, content (JSON-String!), statusCode } +``` + +**Wichtig:** +- Feld heißt `resource`, nicht `uri` — sonst 422 Validation Error +- Payloads müssen Objekte sein, nicht JSON-Strings +- `content` in der Response ist ein JSON-String, muss separat geparst werden +- Jede Operation im Batch zählt einzeln fürs Rate Limit / Write-Budget +- Kein Vorteil gegenüber Einzel-Requests beim Write-Limit, nur weniger HTTP-Roundtrips + +**Entdeckt:** 2026-04-09. Getestet mit Property-Relations — funktioniert, aber kein Write-Limit-Vorteil. + +--- + +## 30. AIMD Rate Limiting für Bulk-Operationen + +**Lektion:** Für lang laufende Bulk-Operationen ist ein adaptiver AIMD-Ansatz (Additive Increase / Multiplicative Decrease) effektiver als ein fester Delay. + +**Warum:** Fester Delay ist entweder zu langsam (verschenkt Kapazität nachts) oder zu schnell (provoziert 429/Write-Limit tagsüber). AIMD konvergiert automatisch zum Optimum und passt sich an wechselnde Bedingungen an (z.B. andere Services die parallel laufen). + +**Pattern:** +```javascript +let delay = 2000; // Start konservativ +const MIN_DELAY = 400; // Minimum für Writes +const MAX_DELAY = 10000; +let successCount = 0; + +// Nach jedem erfolgreichen Request: +successCount++; +if (successCount % 20 === 0) { + delay = Math.max(MIN_DELAY, delay - 50); // Additive Increase +} + +// Bei 429: +delay = Math.min(MAX_DELAY, delay * 2); // Multiplicative Decrease +await sleep(delay * 2); // Extra-Pause vor Retry +``` + +**Ergebnisse:** +- Reads: Von 500ms auf 200ms runtergeregelt, 0 Rate-Limit-Fehler +- Writes: Von 2000ms auf 400–500ms runtergeregelt, gelegentliche 429er werden automatisch abgefangen + +**Entdeckt:** 2026-04-09. Inspiriert von TCP Congestion Control. + +--- + # XI. API-Endpunkt-Referenz | Endpoint | Methode | Zweck | @@ -703,6 +771,7 @@ variation.name; // → '' oder undefined | `/rest/properties/relations` | POST | Eigenschafts-Verknüpfung erstellen (neue Properties) | | `/rest/properties/relations/{relId}` | PUT | Eigenschafts-Verknüpfung aktualisieren | | `/rest/properties/relations/{relId}` | DELETE | Eigenschafts-Verknüpfung löschen | +| `/rest/batch` | POST | Bis zu 20 API-Calls in einem Request bündeln | ---