API-Integrationsleitfaden
Alternative Frontends behandeln NIE-SLA als zugangsdatenfreie, nur-lesbare, cachebare Datenquelle. Proxen oder wiederverwenden Sie keine Admin-Session und rufen Sie keine unversionierten internen Routen direkt auf.
Initialisierungsreihenfolge
- Benutzereingabe normalisieren und nur die Worker-
originbehalten. GET /api/v1anfordern undapi_version === "v1"prüfen.- Fähigkeiten aus den
endpoints- und Capability-Feldern des Manifests ableiten. /api/v1/status?days=30&lite=1für den ersten Screen laden.- Checks, Metrics, Pings oder Latency erst beim Öffnen der Details anfordern.
- Polling bei versteckter Seite pausieren; bei Rückkehr zufälligen Delay ergänzen.
Minimaler Client
export function createNieSlaClient(input) {
const base = new URL(input)
if (base.username || base.password) throw new Error('API base must not contain credentials')
if (base.protocol !== 'https:' && !['localhost', '127.0.0.1', '[::1]'].includes(base.hostname)) {
throw new Error('production API must use HTTPS')
}
const origin = base.origin
async function get(path, params = {}, timeoutMs = 12_000) {
const url = new URL(`/api/v1/${path}`.replace(/\/$/, ''), origin)
for (const [key, value] of Object.entries(params)) {
if (value !== undefined && value !== null && value !== '') url.searchParams.set(key, String(value))
}
const controller = new AbortController()
const timer = setTimeout(() => controller.abort(), timeoutMs)
try {
const response = await fetch(url, {
signal: controller.signal,
credentials: 'omit',
headers: { accept: 'application/json' },
})
const body = await response.json().catch(() => null)
if (!response.ok || body?.ok === false) throw new Error(body?.error || `HTTP ${response.status}`)
return body
} finally {
clearTimeout(timer)
}
}
return {
manifest: async () => {
const body = await get('')
if (body?.api_version !== 'v1') throw new Error('response is not a NIE-SLA v1 manifest')
return body
},
status: options => get('status', { days: 30, lite: 1, ...options }),
checks: (targetId, options) => get('checks', { target_id: targetId, ...options }),
metrics: (agentId, options) => get('metrics', { agent_id: agentId, ...options }),
pings: (agentId, options) => get('pings', { agent_id: agentId, ...options }),
latency: (targetId, options) => get('latency', { target_id: targetId, ...options }),
}
}Das Beispiel prüft HTTP-Status und body.ok, weil ein Kompatibilitätsendpoint einen Geschäftsfehler in einem HTTP 200 liefern kann. Produktionsprojekte sollten auch die Typen der Schlüsselfelder validieren und AbortError als Timeout-Zustand darstellen.
React/Vue-Zustandsmodell
Nicht alles auf einen einzigen loading-Boolean reduzieren; mindestens unterscheiden:
type ResourceState<T> =
| { state: 'idle' }
| { state: 'loading'; previous?: T }
| { state: 'ready'; data: T; warnings: string[] }
| { state: 'empty'; data: T; message: string }
| { state: 'error'; error: string; retryAt?: number }previous während des Refresh behalten, damit Charts nicht leer aufblitzen; warnings[] bedeutet teilweise Datendegradierung und ersetzt nicht erfolgreich geladene Hauptdaten.
Polling und Cache
- Status: 20-60 s empfohlen;
Cache-Controlrespektieren undX-NIE-SLA-Cachebeobachten (X-NStatus-Cachebleibt ein v1-Alias). - Manifest cachet standardmäßig 300 s; Metrics 15; Pings 20; Latency 30.
- Checks nehmen normalisierte
target_id,hoursundlimitin den Cache-Key. - 429 und 5xx nutzen gedeckeltes exponentielles Backoff; 400/403/404 werden nicht unverändert wiederholt.
- Keine zufälligen Query-Parameter zum Umgehen des Worker/Cloudflare-Caches hinzufügen.
Chart-Daten
- Zeitreihen explizit nach Zeitstempel sortieren; nicht auf Antwortreihenfolge verlassen.
- Latenz mit
ok = falseist ein Ausfall- oder Fehlermarker; nicht als0 msplotten. - Bei
format=columnsdtund die Länge jedes Werte-Arrays prüfen. history_downsampledoderpings_downsampledbedeutet heruntergesampelte Daten.- Cloudflare-Checks, Agent-Pings und externe Latenz mit getrennten Legenden und Quell-Labels.
- Fehlende optionale Felder wie Temperatur oder GPU ausblenden, nicht mit Nullen füllen.
Serverintegration
Serveranfragen sind nicht an Browser-CORS gebunden, zählen aber gegen Rate-Limits. Gemeinsamen Cache, vernünftigen User-Agent, Timeouts und begrenzte Retries verwenden; nicht für jede Endnutzer-Anfrage die ganze Historie neu holen. Die öffentliche API hat keine Schreibfähigkeit, und Server sollten keine Admin- oder Agent-Zugangsdaten speichern, um die Grenze zu umgehen.
Browser-Sicherheit
- Immer
credentials: 'omit'mit fetch. - API-Basis kommt aus Deployment-Konfiguration oder validierter Benutzereingabe; URL-Query-Parameter dürfen die Produktionsadresse nie stillschweigend überschreiben.
- Nur HTTPS-Origins erlauben; lokales HTTP ist die Dev-Ausnahme.
- API-Text mit Framework-Standard-Escaping oder
textContentrendern. - Vollständige Antworten nicht in öffentliche Fehler-Telemetrie schreiben; sie können Knotenprofile enthalten, die der Betreiber zwar veröffentlicht hat, die aber weiterhin identifizierend sind.
Weiter mit Status, Checks, Metrics, Pings und Latency für Felder und Parameter der Endpoints.