auto: 1 file changed, 69 insertions(+)
This commit is contained in:
69
DOJO.md
69
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 |
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user