Zum Hauptinhalt springen

API

Endpunkte​

Methode · PfadFunktion
POST /api/v1/queryLeseabfrage. Gesamtes Ergebnis als JSON-Array. Bei Erreichen des Limits truncated-Flag
POST /api/v1/query/streamGleiche Abfrage als NDJSON — eine Zeile pro Datensatz
POST /api/v1/updateSchreibabfrage (TQL wird abgelehnt)
POST /api/v1/formatAbfrage sortieren · einrücken
POST /api/v1/cacheEinzelnen In-Memory-Aktualwert abrufen
GET·POST·DELETE /api/v1/keys · /keys/{id}API-Key-Liste · Ausstellen · Entsorgen
GET·POST /api/v1/loginKonsolen-Login — einziger Pfad unter /api/v1, der ohne Key durchgeht
GET /api/v1/openapi.jsonOpenAPI-3.0.3-Dokumentation (Authentifizierung erforderlich)
GET /api/healthAnonyme Bereitschaftsprüfung — DB · In-Memory · Abfrageprotokoll
GET /admin/metrics · /ping · /healthcheck · /threadsBetriebskennzahlen (Authentifizierung erforderlich)
Nicht authentifizierte Pfade geben 401 zurück — nicht anonym

Pfade, die nicht in der Liste stehen, sind fail-closed und geben 401 zurück. Anonym geöffnet sind nur / · /index.html · /api/health · statische Ressourcen sowie /api/v1/login — das ist die Tür, die den Key ausgibt, daher kann sie keinen Key verlangen.

HeaderErforderlichWert
X-API-KeyJaAusgestellter Schlüssel oder konfigurierter Standardschlüssel
X-LangJaPQL · CQL · SQL · TQL — alles andere ergibt 400
X-ParamsParameterbindung. URL-kodiertes JSON-Objekt
Content-TypeJaapplication/json

Die Abfrage ist der Request-Body selbst. Sie wird nicht in JSON eingepackt.

Lesen — POST /api/v1/query​

curl -X POST -H "X-API-Key: ${PP_DATA_GATEWAY_API_KEY}" -H "X-Lang: PQL" \
-H "Content-Type: application/json" \
-d "SELECT tablename FROM pg_tables WHERE schemaname='pp'" \
https://host:5501/api/v1/query
{"result":"SUCCESS","message":"","truncated":false,
"data":[{"tablename":"mm_asset"},{"tablename":"mm_tag"}]}
truncated nicht ignorieren

Wenn das Ergebnis das Limit (Standardmäßig 100.000 Zeilen) erreicht, bricht das Gateway die Verbindung ab, ohne weiter zu lesen. Wenn truncated auf true gesetzt ist und Sie das nicht beachten, aggregieren Sie mit der Annahme, das abgeschnittene Ergebnis sei vollständig.

Stream — POST /api/v1/query/stream​

Für große Ergebnisse ist dies der richtige Weg. Der Server lädt nicht alles in den Speicher, und der Client erhält die erste Zeile sofort.

curl -X POST -H "X-API-Key: ${PP_DATA_GATEWAY_API_KEY}" -H "X-Lang: PQL" \
-H "Content-Type: application/json" \
-d "SELECT tablename FROM pg_tables WHERE schemaname='pp'" \
https://host:5501/api/v1/query/stream
{"row":{"tablename":"mm_asset"}}
{"row":{"tablename":"mm_tag"}}
{"end":{"count":43,"exec_ms":42,"truncated":false}}

Die Antwort ist application/x-ndjson, und wenn während des Streams ein Fehler auftritt, ist die letzte Zeile nicht end, sondern error.

{"error":{"message":"..."}}
end-Zeile unbedingt prüfen

Die Authentifizierung endet in der Header-Phase, daher beginnt diese Antwort immer mit 200. Fehler danach erscheinen nur im Body — wenn Sie end nicht erhalten haben, ist das Ergebnis nicht abgeschlossen, sondern die Verbindung wurde getrennt, und wenn end.truncated auf true gesetzt ist, wurde am Limit abgeschnitten.

Parameterbindung — X-Params​

Platzhalter in der Abfrage mit :이름 erstellen und in X-Params ein URL-kodiertes JSON-Objekt einfügen.

PARAMS=$(python3 -c "import urllib.parse,json;print(urllib.parse.quote(json.dumps({
'site_id': 'SITE_00001',
'from:ts-long': 1772041960266,
'limit:int': 500
})))")

curl -X POST -H "X-API-Key: ${PP_DATA_GATEWAY_API_KEY}" -H "X-Lang: PQL" \
-H "X-Params: ${PARAMS}" -H "Content-Type: application/json" \
-d "SELECT * FROM pp.mm_tag WHERE site_id = :site_id AND created_at >= :from LIMIT :limit" \
https://host:5501/api/v1/query

Fügen Sie dem Schlüssel :타입 an, um die Konvertierung anzugeben. Ohne Suffix wird der JSON-Typ unverändert übernommen.

SuffixBedeutung
:int · :long · :float · :doubleZahl
:stringZeichenkette
:epoch · :ts-longEpoch-Millisekunden → Zeitstempel
:ts-stringDatumszeichenkette → Zeitstempel

Unbekannte Typsuffixe führen zu 400 PARAM_MISSING — sie werden nicht stillschweigend ignoriert.

Wenn X-Params defekt ist, ist es 400, nicht 500

Nicht dekodierbare Werte (%zz) oder Nicht-JSON-Werte sind Client-Fehler. Früher trat dies als 500 INTERNAL_ERROR auf und wurde als „Server ausgefallen“ gelesen.

Schreiben — POST /api/v1/update​

curl -X POST -H "X-API-Key: ${PP_DATA_GATEWAY_API_KEY}" -H "X-Lang: PQL" \
-H "Content-Type: application/json" \
-d "UPDATE pp.mm_tag SET description = 'reactor inlet' WHERE tag_id = 'TAG_001'" \
https://host:5501/api/v1/update

TQL wird auf diesem Pfad abgelehnt — die Zeitreihen-Engine akzeptiert keine Schreibvorgänge über das Gateway.

Fehlervertrag​

Alle Fehler kommen im selben Umschlag.

{"result":"ERROR","error_code":"QUERY_SYNTAX",
"message":"DDL statements are not allowed: DROP"}
error_codeHTTPBedeutung
AUTH_MISSING401X-API-Key-Header fehlt
AUTH_INVALID401Schlüssel stimmt nicht
PARAM_MISSING400Header · Sprache · Parametertyp-Konvertierung fehlgeschlagen
QUERY_SYNTAX400DDL abgelehnt · Mehrfachanweisung · Syntaxfehler
QUERY_DATA400Datenbeschränkung verletzt
QUERY_CONSTRAINT409Integritätsbeschränkung
QUERY_DEADLOCK409Deadlock
QUERY_AUTH401Authentifizierungsfehler im Backend-Speicher
QUERY_CONNECTION503Keine Verbindung zum Backend
QUERY_TIMEOUT504Backend-Antwort zu langsam
QUERY_ERROR500Sonstiger Ausführungsfehler
QUERY_UNSUPPORTED400Anforderung, die diese Sprache nicht unterstützt
NOT_FOUND404Pfad nicht vorhanden
METHOD_NOT_ALLOWED405Methode nicht vorhanden
UNSUPPORTED_MEDIA_TYPE415Content-Type-Abweichung
API_KEY_NOT_CONFIGURED503Master-Key nicht konfiguriert — kein Anmeldefehler
LOGIN_NOT_CONFIGURED503Konsole-Konto: beide Schlüssel nicht konfiguriert
Die Unterscheidung zwischen 4xx und 5xx ist entscheidend

Syntax · Beschränkung · Daten · Authentifizierung sind Client-Ursachen (4xx), und Verbindung · Timeout sind Infrastruktur-Ursachen (5xx). Wenn beides vermischt wird, kann der Aufrufer nicht unterscheiden, ob „meine Abfrage falsch war“ oder „der Speicher ausgefallen ist“. Auch die Server-Logs trennen nach diesem Kriterium: 4xx als WARN, 5xx als ERROR.

Es gibt zwei API-Keys​

TypWoLebensdauer
StandardschlüsselKonfigurationsdatei data.gateway.api.key (gerendert)Bis zur Konfigurationsänderung
Ausgestellter SchlüsselErstellt über POST /api/v1/keys. Gespeichert wird nur der Salt + SHA-256-DigestLebt nur im Prozess — verschwindet bei Neustart

Der Vergleich erfolgt immer in konstanter Zeit.

Konsolen-Login gibt keinen Key aus

Bei erfolgreichem Login wird der konfigurierte Standardschlüssel unverändert zurückgegeben. Der Grund ist Bootstrap — bei einer Neuinstallation ist der Key-Speicher leer, und jeder Pfad, der einen Key erstellt, erfordert bereits einen Key. Der erste Eindringling muss über Anmeldeinformationen verfügen, die „vor“ dem Speicher existieren, und das ist nur der Schlüssel aus der Konfigurationsdatei.

Daher liest oder schreibt dieser Pfad weder den Key-Speicher noch schreibt er ihn. Er ist die Tür, die auch bei einem Ausfall der DB geöffnet bleiben muss.

Verwandte Dokumentation​