GraphQL Entwickler-Doku (2)
Sie befinden sich auf der Seite: GraphQL Entwickler-Doku (2).
Weitere Seiten in diesem Bereich:
10. Erweiterte GraphQL-Kernfunktionalitäten
Neben den in den vorherigen Kapiteln beschriebenen Funktionen bietet das microtech GraphQL-Schema zwei weitere Kernfunktionalitäten:
System-Felder (_...
) sind Hilfsfunktionen für Typkonvertierung, bedingte Ausführung und Berechnungen. Diese Felder sind in allen Objektkontexten verfügbar – auf Operationsebene, in Tabellen, innerhalb von Datensätzen, und allen anderen Objekten. Sie ermöglichen die Durchführung von Berechnungen, Transformationen und die dynamische Steuerung der Abfragelogik direkt innerhalb der GraphQL-Abfrage.
Erweiterte Schema-Metadaten erweitern die Standard-GraphQL-Introspection um zusätzliche Metadaten über die Datenbankstruktur und Konfiguration. Diese Erweiterungen ermöglichen programmatischen Zugriff auf microtech-spezifische Schema-Informationen.
10.1 System-Felder
10.1.1 Übersicht der System-Felder
System-Felder sind in vier Kategorien unterteilt:
Typisierte Konvertierung und Ausdrucksauswertung:
Konvertierung von Werten und Auswertung von Ausdrücken mit definiertem Zieltyp:
* _int
* _float
* _string
* _boolean
* _bigInt
* _any
* _guid
* _localDate
* _localTime
* _localDateTime
Kontrollfluss:
* _if
- Bedingte Objektrückgabe
* _ifThenElse
- Bedingte Wertrückgabe
Fehlerbehandlung:
* _raise
- Explizites Auslösen von Exceptions
Metadaten-Abfrage:
* _type
- Gibt den __Type
des aktuellen Kontexts zurück
Die folgende Tabelle zeigt alle verfügbaren System-Felder im Detail:
GraphQL-Feld | Rückgabetyp | Beschreibung |
---|---|---|
_int |
Int |
Konvertiert einen Wert in eine 32-Bit-Ganzzahl |
_float |
Float |
Konvertiert einen Wert in eine Fließkommazahl |
_string |
String |
Konvertiert einen Wert in einen String |
_boolean |
Boolean |
Konvertiert einen Wert in einen booleschen Wert oder wertet einen booleschen Ausdruck aus |
_bigInt |
BigInt |
Konvertiert einen Wert in eine Ganzzahl mit bis zu 64 Stellen |
_any |
Any |
Gibt den Wert unverändert zurück oder wertet einen Ausdruck aus |
_guid |
Guid |
Konvertiert einen Wert in eine GUID |
_localDate |
LocalDate |
Konvertiert einen Wert in ein lokales Datum |
_localTime |
LocalTime |
Konvertiert einen Wert in eine lokale Zeit |
_localDateTime |
LocalDateTime |
Konvertiert einen Wert in ein lokales Datum mit Zeit |
_if |
Kontext-Objekt oder null |
Gibt das aktuelle Objekt oder null zurück, abhängig von einer Bedingung |
_ifThenElse |
Any |
Gibt einen von zwei Werten zurück, abhängig von einer Bedingung |
_raise |
Void |
Löst eine Exception mit optionaler Nachricht aus |
_type |
__Type |
Gibt die Typ-Informationen des aktuellen Objektkontexts zurück |
10.1.2 Verwendungszweck und Zusammenspiel mit Variablen
System-Felder ermöglichen es, mit dynamischen Werten zu arbeiten, die während der Abfrageausführung in Variablen gespeichert wurden (siehe Kapitel 9.2 zur @store
-Direktive). Dies erlaubt:
- Dynamische Typkonvertierung: Variablen können je nach Kontext in den benötigten Typ konvertiert werden
- Berechnungen zur Laufzeit: Komplexe Ausdrücke mit Zugriff auf Datenfeldwerte
- Bedingte Abfragelogik: Teile der Abfrage können basierend auf Laufzeitwerten ein- oder ausgeblendet werden
Performance-Hinweis: Die Ausdrucksauswertung erfolgt anwendungsserverseitig. Obwohl dies Rechenzeit kostet, ist es in der Regel effizienter als mehrere Client-Server-Anfragen für bedingte Logik.
10.1.3 Typkonvertierung und Ausdrucksauswertung
Alle Typkonvertierungsfelder (_int
, _float
, _string
, etc.) folgen einem einheitlichen Muster:
- Sie akzeptieren entweder
value
oderexpr
als Parameter (nie beide gleichzeitig) - Bei Verwendung im Kontext eines
Row
-Objekts haben Ausdrücke automatisch Zugriff auf die Datenfelder dieses Datensatzes - Sie konvertieren das Ergebnis in den durch den Feldnamen spezifizierten Typ
10.1.3.1 Gemeinsame Parameter
value
: Ein beliebiger Wert (meist eine Variable), der in den Zieltyp konvertiert werden sollexpr
: Ein Ausdruck, der ausgewertet und dessen Ergebnis in den Zieltyp konvertiert werden soll- Für
_boolean
muss dies ein Ausdruck vom TypSlowBooleanExpression
sein (siehe Kapitel 5.4) - Für alle anderen Felder muss dies ein Ausdruck vom Typ
SlowAnyExpression
sein (siehe Kapitel 5.5)
10.1.3.2 Beispiele
Wertausgabe via _any
direkt auf Operationsebene:
query (
$variable: Any = 42
) {
# Direkte Verwendung auf Operationsebene
variableWert: _any(value: $variable)
# Weiterhin normaler Zugriff auf Tabellen
tblProducts {
rowsRead {
fldArtNr
}
}
}
Berechneter Ausdruck mit Datenfeldnutzung (expr
):
query {
tblProducts {
rowsRead {
fldArtNr
fldSuchBeg
fldLagMge
fldStdPreis
# Berechnung eines abgeleiteten Wertes aus Standardpreis und Lagermenge
gesamtwert: _float(expr: {
mul: [
{ field: fldLagMge },
{ field: fldStdPreis }
]
})
# Prüfen, ob Lagerbestand vorhanden ist
hatBestand: _boolean(expr: {
gt: [
{ field: fldLagMge },
{ value: 0 }
]
})
}
}
}
10.1.3.3 Unterschied zur direkten Feldabfrage
Während Datenfelder direkt über fld...
-Felder abgefragt werden können, bieten System-Felder zusätzliche Möglichkeiten:
- Komplexe Berechnungen: System-Felder mit
expr
erlauben Berechnungen mit mehreren Datenfeldern und konstanten Werten - Typkonvertierung: System-Felder erzwingen einen bestimmten Rückgabetyp, unabhängig vom Quelldatentyp
- Bedingte Logik: In Kombination mit
_if
und_ifThenElse
ermöglichen sie dynamische Abfragen
10.1.3.4 Fehlerbehandlung bei Typkonvertierung
Null-Behandlung: Alle System-Felder folgen dem Prinzip "null in → null out". Wenn der value
-Parameter oder das Ergebnis eines expr
-Ausdrucks null
ist, gibt das System-Feld ebenfalls null
zurück.
Konvertierungsfehler: Ungültige Typkonvertierungen (z.B. String "abc" zu Int) lösen Laufzeitfehler aus, die nach Standard-GraphQL-Regeln behandelt werden.
10.1.4 Bedingte Ausführung mit _if
und _ifThenElse
10.1.4.1 Das _if
-Feld
Das _if
-Feld prüft eine Bedingung und gibt basierend auf dem Ergebnis das aktuelle Objekt oder null
zurück.
Parameter:
* value
: (Optional) Ein boolescher Wert (meist eine Variable)
* expr
: (Optional) Ein SlowBooleanExpression
-Ausdruck
Hinweis: Es muss genau ein Parameter, entweder value
oder expr
, angegeben werden.
Rückgabe:
* Wenn die Bedingung true
ist: das aktuelle Objekt (der Kontext, auf dem _if
aufgerufen wurde)
* Wenn die Bedingung false
oder null
ist: null
Beispiel:
query {
tblProducts {
rowsRead {
fldArtNr
fldSuchBeg
fldLagMge
# Nur wenn Lagermenge > 0, Details anzeigen
details: _if(expr: {
gt: [{ field: fldLagMge }, { value: 0 }]
}) {
fldStdPreis
fldLagMge
}
}
}
}
In diesem Beispiel wird das details
-Objekt nur für Artikel mit fldLagMge > 0
zurückgegeben, andernfalls ist es null
.
10.1.4.2 Das _ifThenElse
-Feld (If-Then-Else)
Das _ifThenElse
-Feld ermöglicht eine bedingte Auswahl zwischen zwei Werten, ähnlich dem ternären Operator in vielen Programmiersprachen.
Parameter:
* value
: (Optional) Ein boolescher Wert (meist eine Variable)
* expr
: (Optional) Ein SlowBooleanExpression
-Ausdruck
* then
: (Optional) Der Wert, der zurückgegeben wird, wenn die Bedingung true
ist (standardmäßig null
)
* else
: (Optional) Der Wert, der zurückgegeben wird, wenn die Bedingung false
oder null
ist (standardmäßig null
)
Hinweis: Es muss genau ein Parameter für die Bedingung, entweder value
oder expr
, angegeben werden.
Beispiel:
query {
tblProducts {
rowsRead {
fldArtNr
fldSuchBeg
fldLagMge
# Statustext je nach Lagermenge
lagerStatus: _ifThenElse(
expr: { gt: [{ field: fldLagMge }, { value: 0 }] },
then: "Verfügbar",
else: "Nicht auf Lager"
)
}
}
}
In diesem Beispiel wird für jeden Artikel abhängig von der Lagermenge ein entsprechender Statustext zurückgegeben.
Wichtiger Hinweis: Das _ifThenElse
-Feld kann nicht innerhalb eines Ausdrucks (expr
) verwendet werden.
10.1.5 Fehlerbehandlung mit _raise
Das _raise
-Feld ermöglicht das explizite Auslösen einer Exception mit einer optionalen Fehlermeldung.
Parameter:
* message
: (Optional) Ein String mit der Fehlermeldung
Rückgabetyp: Void
(der Aufruf kehrt nie normal zurück)
Anwendungsfälle: * Validierung von Eingabedaten * Abbruch der Abfrage bei unerwünschten Zuständen * Erzwingen von Fehlern für Testzwecke
Beispiel:
query {
tblProducts {
rowsRead {
fldArtNr
fldLagMge
# Fehler auslösen, wenn Lagermenge negativ ist
_if(expr: { lt: [{ field: fldLagMge }, { value: 0 }] }) {
_raise(message: "Negative Lagermenge gefunden!")
}
}
}
}
In diesem Beispiel wird ein Fehler mit der Nachricht "Negative Lagermenge gefunden!" ausgelöst, wenn ein Artikel mit einer negativen Lagermenge gefunden wird.
10.1.6 Realisierung komplexer Logik (durch Kombination mit Direktiven)
System-Felder können mit den in Kapitel 9 beschriebenen Direktiven kombiniert werden, insbesondere mit @store
(Kapitel 9.2) und @onNull
(Kapitel 9.3), um komplexe Logik zu realisieren.
10.1.6.1 Beispiel: Bedingte Anzeige mit dynamischen Variablen
query ($hatBestand: Boolean = false) {
tblProducts {
rowsRead {
fldArtNr
fldSuchBeg
# Prüfen, ob Artikel einen Lagerbestand hat
_boolean(expr: {
gt: [{ field: fldLagMge }, { value: 0 }]
}) @store(in: $hatBestand)
# Details nur anzeigen, wenn Lagerbestand vorhanden
details: _if(value: $hatBestand) {
fldLagMge
fldStdPreis
}
}
}
}
In diesem Beispiel wird die Variable $hatBestand
dynamisch aufgrund des Lagerbestands jedes Artikels aktualisiert und zur Steuerung der Anzeige weiterer Details verwendet.
10.1.6.2 Beispiel: Komplexe Bedingungslogik
query {
tblProducts {
rowsRead {
fldArtNr
fldGspKz
fldLagMge
# Bedingter Wert basierend auf Artikel-Status
lieferStatus: _ifThenElse(
expr: {
and: [
# Artikel ist nicht gesperrt
{ not: { field: fldGspKz } },
# Lagermenge > 0
{ gt: [{ field: fldLagMge }, { value: 0 }] }
]
},
then: "Lieferbar",
else: "Nicht lieferbar"
)
}
}
}
Dieses Beispiel zeigt, wie komplexe Bedingungslogik mit verschachtelten Ausdrücken und mehreren Datenfeldern realisiert werden kann.
10.1.7 Praktische Einsatzbeispiele
10.1.7.1 Formatierung und Anreicherung von Daten
query {
tblProducts {
rowsRead {
fldArtNr
fldSuchBeg
# Artikelnummer und Suchbegriff kombinieren
artikelText: _string(expr: {
add: [
{ field: fldArtNr },
{ value: " - " },
{ field: fldSuchBeg }
]
})
}
}
}
10.1.7.2 Dynamische Filterung innerhalb eines Objekts
query {
tblProducts {
rowsRead {
fldArtNr
fldSuchBeg
fldGspKz
# Nur nicht gesperrte Artikel mit Warengruppe anzeigen
warengruppe: _if(expr: {
not: { field: fldGspKz }
}) {
rowWgrNr {
fldWgrNr
fldBez
}
}
}
}
}
10.1.7.3 Bedingte Darstellung mit Datumsverarbeitungen
query {
tblTransactions {
rowsRead {
fldBelegNr
fldDat
# Datumsverarbeitung: Aktuelles Datum
aktuellesDatum: _localDate(expr: { fnGetAktDate: [] })
# Datum ein Jahr zurück (12 Monate)
jahresVergleich: _localDate(expr: {
fnIncDate: [
{ fnGetAktDate: [] },
{ value: 0 },
{ value: -12 }
]
})
# Prüfen ob Beleg älter als ein Jahr ist
istAlt: _boolean(expr: {
lt: [
{ field: fldDat },
{ fnIncDate: [
{ fnGetAktDate: [] },
{ value: 0 },
{ value: -12 }
]}
]
})
}
}
}
Mit dieser umfassenden Palette an System-Feldern bietet die microtech GraphQL-Schnittstelle äußerst flexible Möglichkeiten, komplexe Datenabfragen und -manipulationen direkt in der Abfrage zu definieren und so die Effizienz und Lesbarkeit Ihrer Anwendungen zu verbessern.
10.1.8 Metadaten-Abfrage mit _type
Das _type
-Feld ermöglicht den direkten Zugriff auf die Typ-Informationen des aktuellen Objektkontexts. Es gibt ein __Type
-Objekt zurück, das alle Schema-Informationen einschließlich der microtech-spezifischen Extensions enthält.
10.1.8.1 Funktionsweise
_type
benötigt keine Parameter und gibt immer den __Type
des Objekts zurück, auf dem es aufgerufen wird. Dies funktioniert in allen Kontexten – auf Operationsebene, in Tabellen, in Datensätzen und allen anderen Objekttypen.
10.1.8.2 Anwendungsfälle
- Schema-Exploration: Erkunden der verfügbaren Felder und deren Typen im aktuellen Kontext
- Dynamische Metadaten-Abfrage: Zugriff auf microtech-spezifische Extensions ohne den Typ-Namen zu kennen
- Debugging: Überprüfung der tatsächlichen Typ-Struktur zur Laufzeit
- Generische Abfragen: Erstellen von Abfragen, die mit verschiedenen Objekttypen funktionieren
10.1.8.3 Beispiele
Grundlegende Verwendung:
query {
# Typ-Informationen der Query-Operation
_type {
name # "Query"
kind # "OBJECT"
}
tblProducts {
# Typ-Informationen der Tabelle
_type {
name # z.B. "ProductsTableQueryRead"
mapExtensions # Tabellen-spezifische Metadaten
}
rowsRead {
# Typ-Informationen des Row-Objekts
_type {
name # z.B. "ProductRowQueryRead"
fields(excludeSystem: true) {
name
typeName
}
}
}
}
}
Zugriff auf erweiterte Metadaten:
query {
tblProducts {
_type {
# Direkt auf Extensions zugreifen
mapExtensions # Alle Extensions als Map
anyExtensionValue(name: "flags") # Spezifische Extension
# Strukturierte Extension-Informationen
extensions {
name
value
}
}
}
}
Kombination mit anderen System-Feldern:
query ($showDebugInfo: Boolean = false) {
tblProducts {
rowsRead {
fldArtNr
# Bedingte Debug-Informationen
debugInfo: _if(value: $showDebugInfo) {
_type {
name
fields {
name
typeName
isDeprecated
}
}
}
}
}
}
Das _type
-Feld ist besonders nützlich für die Entwicklung generischer Tools und für das Debugging komplexer GraphQL-Abfragen.
10.2 Erweiterte Schema-Metadaten
Das microtech GraphQL-Schema erweitert die Standard-Introspection um zusätzliche Metadaten. Diese Erweiterungen ermöglichen programmatischen Zugriff auf erweiterte Schema-Informationen wie Datenbankstruktur, Tabellenbeziehungen und Konfigurationsdetails.
10.2.1 Erweiterte Introspection-Objekte
Alle Standard-GraphQL-Introspection-Objekte (__Schema
, __Type
, __Field
, __InputValue
, __EnumValue
, __Directive
) wurden um zusätzliche Extension-Felder erweitert.
Hinweis zur Verwendung in Entwicklungsumgebungen: Die meisten GraphQL-IDEs und interaktiven Oberflächen verwenden ihre eigene Definition der Introspection-Typen basierend auf der Standard-GraphQL-Spezifikation. Diese Tools erkennen die microtech-spezifischen Erweiterungen nicht und zeigen möglicherweise Fehler oder Warnungen an, wenn Sie Extension-Felder wie mapExtensions
, anyExtensionValue
oder typeName
verwenden.
Diese Warnungen können ignoriert werden – die Abfragen werden trotzdem korrekt ausgeführt. Es handelt sich um ein reines Anzeigeproblem der Entwicklungsumgebung, nicht um einen tatsächlichen Fehler. Dieses Verhalten ist vergleichbar mit der in Kapitel 6.1.2 beschriebenen Situation beim Variable
-Typ.
10.2.2 Extension-Zugriff
10.2.2.1 Das mapExtensions
-Feld (empfohlen)
Das mapExtensions
-Feld (Rückgabetyp: Any
) stellt alle Extension-Werte in einem Map-Format zur Verfügung und ist der effizienteste Weg für den Zugriff auf Extension-Daten:
Syntax:
mapExtensions # Gibt alle Extensions als Key-Value-Map zurück (Any)
Dieses Format sollte bevorzugt verwendet werden, wenn nur die Extension-Werte benötigt werden.
10.2.2.2 Das extensions
-Feld
Das extensions
-Feld gibt eine Liste von Extension-Objekten mit strukturierten Metadaten zurück:
Syntax:
extensions {
name # String: Name der Extension
typeName # String: GraphQL-Typ der Extension
description # String: Beschreibung der Extension
value # Any: Der eigentliche Wert der Extension
}
Verwenden Sie dieses Format nur, wenn Sie zusätzlich zu den Werten auch Typ-Informationen und Beschreibungen benötigen.
10.2.2.3 Das anyExtensionValue
-Feld
Das anyExtensionValue(name: String!)
-Feld (Rückgabetyp: Any
) ermöglicht den direkten Zugriff auf den Wert einer spezifischen Extension:
Syntax:
anyExtensionValue(name: "extensionName") # String! parameter ist erforderlich
10.2.3 Zusätzliche microtech-spezifische Felder
10.2.3.1 Das typeName
-Feld
Die Introspection-Objekte __Field
und __InputValue
wurden um ein typeName
-Feld erweitert, das eine String-Repräsentation des GraphQL-Typs liefert. Im Gegensatz zur Standard-Introspection wird die Typ-Information direkt als String bereitgestellt, einschließlich Non-Null- und List-Modifikatoren. Das typeName
-Feld kann Werte wie "Int"
, "Int!"
, "[Type]"
, "[Type!]"
, "[Type]!"
oder "[Type!]!"
enthalten.
Beispiel aus dem Schema:
{
"name": "aceByTaxCode",
"description": "",
"args": [
{
"name": "taxCode",
"description": "",
"typeName": "Int"
}
],
"typeName": "AmountCompositionEntryQuery",
"isDeprecated": false
},
{
"name": "aces",
"description": "",
"args": [],
"typeName": "[AmountCompositionEntryQuery]",
"isDeprecated": false
}
Das typeName
-Feld zeigt direkt "[AmountCompositionEntryQuery]"
für Listen und "Int"
für einfache Typen, anstatt die bis zu 4-fach verschachtelte ofType
-Struktur der Standard-Introspection zu verwenden.
10.2.3.2 Der excludeSystem
-Parameter
Das fields
-Feld von __Type
unterstützt einen zusätzlichen excludeSystem
-Parameter:
Syntax:
fields(includeDeprecated: true, excludeSystem: true)
Wenn excludeSystem: true
gesetzt ist, werden die System-Felder (_...
) aus der Rückgabe ausgeschlossen.
10.2.3.3 Einzelzugriffs-Felder
Alle Introspection-Objekte wurden um direkte Zugriffsmethoden für ihre Listen-Felder erweitert. Diese Felder ermöglichen den effizienten Zugriff auf einzelne Elemente ohne das Abrufen kompletter Listen.
Verfügbare Einzelzugriffs-Felder:
Introspection-Objekt | Feld | Alternative zu |
---|---|---|
__Schema |
type(name: String!) |
types -Liste |
__Schema |
directive(name: String!) |
directives -Liste |
__Type |
field(name: String!) |
fields -Liste |
__Type |
inputField(name: String!) |
inputFields -Liste |
__Type |
enumValue(name: String!) |
enumValues -Liste |
__Field , __Directive |
arg(name: String!) |
args -Liste |
Wichtig: Alle Felder geben null
zurück, wenn das gesuchte Element nicht existiert.
Beispiel:
query {
__schema {
# Direkter Zugriff auf einen Typ
type(name: "SetBooleanFieldInput") {
# Direkter Zugriff auf ein Input-Feld
inputField(name: "text") {
name
typeName
}
}
# Direkter Zugriff auf eine Direktive
directive(name: "onNull") {
name
# Direkter Zugriff auf ein Argument der Direktive
arg(name: "do") {
name
typeName
}
}
}
tblClient {
rowRead {
_type {
# Direkter Zugriff auf ein Feld
field(name: "fldID") {
name
# Direkter Zugriff auf ein Argument des Feldes
arg(name: "as") {
name
type {
# Direkter Zugriff auf einen Enum-Wert
enumValue(name: "TEXT") {
name
}
}
}
}
}
}
}
}
Diese Erweiterungen reduzieren den Datenübertragungsaufwand erheblich, wenn nur spezifische Schema-Elemente benötigt werden.
10.2.4 Praktische Beispiele
10.2.4.1 Tabellen-Informationen abfragen
Abfrage:
query {
__type(name: "PostalCodesTableQueryRead") {
name
kind
extensions {
name
typeName
description
value
}
mapExtensions
anyExtensionValue(name:"flags")
}
}
Antwort:
{
"data": {
"__type": {
"name": "PostalCodesTableQueryRead",
"kind": "OBJECT",
"extensions": [
{
"name": "type",
"typeName": "DBStrukturKzEnum",
"description": "",
"value": "dbsPLZ"
},
{
"name": "dbAlias",
"typeName": "DbAliasEnum",
"description": "",
"value": "dbaGlobal"
},
{
"name": "shortName",
"typeName": "String!",
"description": "",
"value": "Plz"
},
{
"name": "name",
"typeName": "String!",
"description": "",
"value": "Postleitzahlen"
},
{
"name": "shortDescription",
"typeName": "String!",
"description": "",
"value": "Postleitzahlen"
},
{
"name": "description",
"typeName": "String!",
"description": "",
"value": "Postleitzahlen"
},
{
"name": "flags",
"typeName": "[DBSFlagEnum!]!",
"description": "",
"value": [
"dbsfSetVgbIndex",
"dbsfSelFelder",
"dbsfSelSortierungen",
"dbsfNeedRecreate",
"dbsfFilterDef",
"dbsfAllowIndexSuche",
"dbsfCreated",
"dbsfInternalAutoIncStruktur",
"dbsfTableExists",
"dbsfHatBereichLoeschenCommand",
"dbsfVerzMehrfachSuche",
"dbsfCommandDesigner",
"dbsfUnicodeUnterstuetzung",
"dbsfAllowClientCaching",
"dbsfInternalClientCaching",
"dbsfInternalLz4RecordCompression",
"dbsfInternalKeylessIndices",
"dbsfInfoGraphQLRecordType",
"dbsfInfoGraphQLRootTable"
]
}
],
"mapExtensions": {
"type": "dbsPLZ",
"dbAlias": "dbaGlobal",
"shortName": "Plz",
"name": "Postleitzahlen",
"shortDescription": "Postleitzahlen",
"description": "Postleitzahlen",
"flags": [
"dbsfSetVgbIndex",
"dbsfSelFelder",
"dbsfSelSortierungen",
"dbsfNeedRecreate",
"dbsfFilterDef",
"dbsfAllowIndexSuche",
"dbsfCreated",
"dbsfInternalAutoIncStruktur",
"dbsfTableExists",
"dbsfHatBereichLoeschenCommand",
"dbsfVerzMehrfachSuche",
"dbsfCommandDesigner",
"dbsfUnicodeUnterstuetzung",
"dbsfAllowClientCaching",
"dbsfInternalClientCaching",
"dbsfInternalLz4RecordCompression",
"dbsfInternalKeylessIndices",
"dbsfInfoGraphQLRecordType",
"dbsfInfoGraphQLRootTable"
]
},
"anyExtensionValue": [
"dbsfSetVgbIndex",
"dbsfSelFelder",
"dbsfSelSortierungen",
"dbsfNeedRecreate",
"dbsfFilterDef",
"dbsfAllowIndexSuche",
"dbsfCreated",
"dbsfInternalAutoIncStruktur",
"dbsfTableExists",
"dbsfHatBereichLoeschenCommand",
"dbsfVerzMehrfachSuche",
"dbsfCommandDesigner",
"dbsfUnicodeUnterstuetzung",
"dbsfAllowClientCaching",
"dbsfInternalClientCaching",
"dbsfInternalLz4RecordCompression",
"dbsfInternalKeylessIndices",
"dbsfInfoGraphQLRecordType",
"dbsfInfoGraphQLRootTable"
]
}
}
}
10.2.4.2 Vollständige Schema-Introspection
Für umfassende Schema-Analyse kann die folgende Abfrage verwendet werden:
query IntrospectionQuery {
__schema {
queryType @onNull(returnValue:skip) { name }
mutationType @onNull(returnValue:skip) { name }
subscriptionType @onNull(returnValue:skip) { name }
types { ...FullType }
directives { ...Directive }
}
}
fragment FullType on __Type {
kind
name @onNull(returnValue:skip)
description @onNull(returnValue:skip)
fields(includeDeprecated: true excludeSystem: true) @onNull(returnValue:skip) { ...Field }
inputFields @onNull(returnValue:skip) { ...InputValue }
interfaces @onNull(returnValue:skip) { ...TypeRef }
enumValues(includeDeprecated: true) @onNull(returnValue:skip) { ...EnumValue }
possibleTypes @onNull(returnValue:skip) { ...TypeRef }
extensions: mapExtensions @onNull(returnValue:skip)
}
fragment InputValue on __InputValue {
name
description
typeName
defaultValue @onNull(returnValue:skip)
extensions: mapExtensions @onNull(returnValue:skip)
}
fragment TypeRef on __Type {
kind
name @onNull(returnValue:skip)
ofType @onNull(returnValue:skip) {
kind
name @onNull(returnValue:skip)
ofType @onNull(returnValue:skip) {
kind
name @onNull(returnValue:skip)
ofType @onNull(returnValue:skip) {
kind
name @onNull(returnValue:skip)
}
}
}
}
fragment Directive on __Directive {
name
description
locations
args { ...InputValue }
extensions: mapExtensions @onNull(returnValue:skip)
}
fragment Field on __Field {
name
description
args @onNull(returnValue:skip) { ...InputValue }
typeName
isDeprecated
deprecationReason @onNull(returnValue:skip)
extensions: mapExtensions @onNull(returnValue:skip)
}
fragment EnumValue on __EnumValue {
name
description @onNull(returnValue:skip)
isDeprecated
deprecationReason @onNull(returnValue:skip)
extensions: mapExtensions @onNull(returnValue:skip)
}
Diese Abfrage nutzt die @onNull
-Direktive (siehe Kapitel 9.3) um null
-Werte zu handhaben und die Ausgabe zu bereinigen.
10.2.5 Anwendungsfälle
Die erweiterten Metadaten ermöglichen:
- Automatische Tool-Generierung: Basierend auf Schema-Metadaten
- Schema-Exploration: Programmatischer Zugriff auf erweiterte Schema-Informationen
- Entwicklungsunterstützung: Besseres Verständnis der zugrundeliegenden Strukturen
10.2.6 Bewährte Verfahren
10.2.6.1 Effiziente Abfragen
- Bevorzugen Sie
mapExtensions
: Für den Zugriff auf Extension-Werte - Verwenden Sie
anyExtensionValue
: Für einzelne, bekannte Extensions - Nutzen Sie
excludeSystem: true
: Um System-Felder bei der Schema-Analyse auszuschließen - Kombinieren Sie mit
@onNull
: Für saubere JSON-Ausgaben
10.2.6.2 Tool-Entwicklung
- Schema-Caching: Die erweiterten Metadaten ändern sich selten und können aggressiv gecacht werden
- Robuste Fehlerbehandlung: Tools sollten auch funktionieren, wenn spezifische Extensions fehlen
- Typname-Nutzung: Verwenden Sie
typeName
für einfachere Typ-Verarbeitung
Hinweis: Die verfügbaren Extension-Namen und -Werte können sich je nach microtech Software-Version und Konfiguration unterscheiden. Tools sollten flexibel auf verfügbare Extensions reagieren.
Mutationen mit GraphQL
Im nächsten Kapitel stellen wir Ihnen das Mutationen-Konzept vor.
Weitere Informationen in diesem Bereich: