Guide d'intégration API
Les frontends alternatifs traitent NIE-SLA comme une source de données sans identifiants, en lecture seule et cacheable. Ne proxiez pas et ne réutilisez pas une Session Admin, et n'appelez pas directement les routes internes non versionnées.
Ordre d'initialisation
- Normalisez l'entrée utilisateur et ne gardez que l'
origindu Worker. - Demandez
GET /api/v1et vérifiezapi_version === "v1". - Décidez des fonctionnalités disponibles depuis les champs de capacités et
endpointsdu Manifest. - Récupérez
/api/v1/status?days=30&lite=1pour le premier écran. - Demandez checks, metrics, pings ou latency seulement quand l'utilisateur ouvre les détails.
- Mettez en pause le polling quand la page est masquée ; ajoutez un délai aléatoire au retour.
Client minimal
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 }),
}
}L'exemple vérifie à la fois le statut HTTP et body.ok, parce qu'un endpoint de compatibilité peut renvoyer une erreur métier dans un HTTP 200. Les projets de production doivent aussi valider les types des champs clés et présenter AbortError comme un état de dépassement.
Modèle d'état React/Vue
Ne réduisez pas tout à un seul booléen loading ; distinguez au moins :
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 }Conservez previous pendant le rafraîchissement pour que les graphiques ne clignotent pas à vide ; warnings[] signifie une dégradation partielle des données et ne remplace pas les données principales chargées.
Polling et cache
- Status : 20-60 s recommandé ; respectez
Cache-Controlet observezX-NIE-SLA-Cache(X-NStatus-Cachereste un alias v1). - Le Manifest se cache 300 s par défaut ; Metrics 15 ; Pings 20 ; Latency 30.
- Checks incluent le
target_id,hoursetlimitnormalisés dans la clé de cache. - 429 et 5xx utilisent un backoff exponentiel plafonné ; 400/403/404 ne sont pas réessayés tels quels.
- N'ajoutez pas de paramètres aléatoires pour contourner le cache Worker/Cloudflare.
Données de graphiques
- Triez les séries temporelles par horodatage explicitement ; ne comptez pas sur l'ordre de réponse.
- La latence avec
ok = falseest un marqueur de panne ou de défaut ; ne la tracez pas à0 ms. - Avec
format=columns, vérifiezdtet la longueur de chaque tableau de valeurs. history_downsampledoupings_downsampledsignifie que les données ont été sous-échantillonnées.- Les sondes Cloudflare, pings Agent et latence externe utilisent des légendes et étiquettes de source différentes.
- Masquez les séries des champs optionnels comme la température ou le GPU quand ils manquent ; ne remplissez pas de zéros.
Intégration serveur
Les requêtes serveur ne sont pas soumises au CORS navigateur mais comptent quand même dans les limites de débit. Utilisez un cache partagé, un User-Agent raisonnable, des délais et des nouvelles tentatives bornées ; ne récupérez pas tout l'historique pour chaque requête d'utilisateur final. L'API publique n'a aucune capacité d'écriture, et les serveurs ne doivent pas stocker d'identifiants admin ou Agent pour contourner la frontière.
Sécurité navigateur
- Toujours
credentials: 'omit'avec fetch. - La base API vient de la configuration de déploiement ou d'une entrée utilisateur validée ; les paramètres d'URL ne doivent jamais remplacer silencieusement l'adresse de production.
- Autorisez uniquement les origines HTTPS ; le HTTP local est l'exception de développement.
- Rendez le texte API avec l'échappement par défaut du framework ou
textContent. - N'écrivez pas les réponses complètes dans la télémétrie d'erreur publique ; elles peuvent contenir des profils de nœuds que le déployeur a choisi d'exposer mais qui restent identifiants.
Continuez avec Status, Checks, Metrics, Pings et Latency pour les champs et paramètres de chaque endpoint.