Home Up PDF Prof. Dr. Ingo Claßen
Übung GraphQL -ADBKT

Übung GraphQL

Einleitung

In dieser Aufgabe sollen sie aus vereinfachten GraphQL-Abfragen Postgres-SQL-Code erzeugen, der JSON-Strukturen als Antwort zurückliefert.

Grundlage für die Erzeugung sind Tabellen, die durch Fremdschlüssel miteinander verbunden sind, wie im folgenden Beispiel. GraphQL ermöglicht einen einfachen Zugriff auf solche Strukturen und liefert JSON zurück, das dann in Anwendungsprogrammen direkt weiterverwendet werden kann.

Konkret besteht ihre Aufgabe darin, in Python folgende Funktion zu implementieren:

def gql_to_json(gql: AST) -> str

Die Abfragen werden als Abstract Syntax Trees (AST) bereitgestellt:

@dataclass
class Cond():
    l: str
    r: str

@dataclass
class AST():
    name: str
    attr: list[str]
    cond: Optional[Cond] = None
    sub: Optional['AST'] = None

Abfrage AST
t1 {
      a
}
AST(name='t1', attr=['a'], cond=None, sub=None)

Notebook

Tabellen

Zum Testen werden folgenden Beispieldaten bereitgestellt.

t1 t2 t3

Beispielabfragen

Im Folgenden finden sie eine Reihe von Beispielabfragen, die für ihren Code als Test dienen sollen.

Abfrage Bedeutung Erwartetes JSON-Ergebnis
Beispiel 01
t1 {
    a
}
Alle Objekte aus Tabelle "t1". Es soll nur Spalte "a" ausgegeben werden.
[
      {
          "a": "a1"
      },
      {
          "a": "a2"
      }
]
Beispiel 02
t1 (a: 'a1') {
    a
    b
}
Alle Objekte aus Tabelle "t1", bei denen die Spalte "a" den Wert 'a1' hat. Es sollen die Spalten "a" und "b" ausgegeben werden.
[
    {
        "a": "a1",
        "b": "b1"
    }
]
Beispiel 03
t1 (a: 'a1') {
    a
    b
    t2 {
        c
        d
    }
}
Wie Beispiel 02. Es sollen zusätzlich alle "t2"-Objekte ausgegeben werden, die mit den "t1"-Objekten verbunden sind.
[
    {
        "a": "a1",
        "b": "b1",
        "t2": [
            {
                "c": "c11",
                "d": "d11"
            },
            {
                "c": "c12",
                "d": "d12"
            }
        ]
    }
]
Beispiel 04
t1 (a: 'a1') {
    a
    b
    t2 (d: 'd12') {
        c
        d
    }
}
Wie Beispiel 03. Die verbundenen Objekte sollen gefiltert werden, die Spalte "d" soll den Wert 'd12' haben.
[
    {
        "a": "a1",
        "b": "b1",
        "t2": [
            {
                "c": "c12",
                "d": "d12"
            }
        ]
    }
]
Beispiel 05
t1 (a: 'a1') {
    a
    b
    t2 (d: 'd12') {
        c
        d
        t3 {
            e
            f
        }
    }
}
Wie Beispiel 04. Es soll eine weitere Ebene mit den verbundenen "t3"-Objekten ausgegeben werden
[
    {
        "a": "a1",
        "b": "b1",
        "t2": [
            {
                "c": "c12",
                "d": "d12",
                "t3": [
                    {
                        "e": "e103",
                        "f": "f103"
                    },
                    {
                        "e": "e104",
                        "f": "f104"
                    }
                ]
            }
        ]
    }
]
Beispiel 06
t1 (a: 'a1') {
    a
    b
    t2 (d: 'd12') {
        c
        d
        t3 (f: 'f103') {
            e
            f
        }
    }
}
Wie Beispiel 05. Die verbundenen "t3"-Objekte sollen gefiltert werden, die Spalte "f" soll den Wert 'f103' haben.
[
    {
        "a": "a1",
        "b": "b1",
        "t2": [
            {
                "c": "c12",
                "d": "d12",
                "t3": [
                    {
                        "e": "e103",
                        "f": "f103"
                    }
                ]
            }
        ]
    }
]

Hinweise zur Lösung

Gehen sie bei der Implementierung wie folgt vor:

  • AST traversieren und eine Postgres-Query erzeugen
  • Diese Query muss geeignete JSON-Erzeugungsfunktionen verwenden
  • Query an die Datenbank senden und Ergebnis ausgeben
  • Beachten sie, dass sie die Namen der Tabellen und Spalten aus der GraphQL-Query entnehmen und nicht hart kodieren
  • Um verbundene Objekte auszugeben, müssen sie Datenbank-Joins erzeugen
  • Die dazu notwendigen Fremd- und Primärschlüssel müssen sie über die Datenbank-Metadaten ermitteln