. Name und Salär der Angestellten aus Luzern mit Salär zwischen 5000 und 8000 nach Salär aufsteigend geordnet.
ifdef::exercise_solution[]
+
[example,title=""]
{nbsp}
{nbsp}
endif::exercise_solution[]
=====
.[#postgraphile-]#Q{counter:query_number}: Name und Salär der Angestellten aus Luzern mit Salär zwischen 5000 und 8000 nach Salär aufsteigend geordnet.#
{sp}
[example,title=""]
.Angestellte aus Luzern im Salärbereich (5000,8000) sortiert
. Alle Projekte mit Projektnummer, Bezeichnung, Dauer, Aufwand und Startzeit inklusive Name des Projektleiters.
ifdef::exercise_solution[]
+
.[#postgraphile-]#Q{counter:query_number}: Alle Projekte mit Projektnummer, Bezeichnung, Dauer, Aufwand und Startzeit inklusive Name des Projektleiters.#
{sp}
[example,title=""]
=====
.Projektübersicht
=====
ifdef::exercise_solution[]
[source%autofit,graphql]
----
query alleProjekte {
...
...
@@ -211,18 +252,25 @@ query alleProjekte {
}
}
----
=====
endif::exercise_solution[]
ifndef::exercise_solution[]
{nbsp}
{nbsp}
{nbsp}
endif::exercise_solution[]
=====
{blank}
=== Aufgabe {counter:ex_number}: Create, Update und Delete
. Fügen Sie einen neuen Angestellten ein mit der persnr. 5000 und weiteren Werten für die Attribute name, chef, salaer, eintrittsdatum (Bonus NULL lassen).
ifdef::exercise_solution[]
+
.[#postgraphile-]#Q{counter:query_number}: Fügen Sie einen neuen Angestellten ein mit der `persnr=5000` und weiteren Werten für die Attribute `name`, `chef`, `salaer`, `eintrittsdatum` (Bonus `NULL` lassen).#
{sp}
[example,title=""]
=====
.Erstellen eines neuen Angestellten
ifdef::exercise_solution[]
[source%autofit,graphql]
----
mutation {
...
...
@@ -249,7 +297,17 @@ mutation {
}
}
----
endif::exercise_solution[]
ifndef::exercise_solution[]
{nbsp}
{nbsp}
{nbsp}
endif::exercise_solution[]
.Resultat der Mutation
ifdef::exercise_solution[]
[source%autofit,json]
----
{
...
...
@@ -266,15 +324,22 @@ mutation {
}
}
----
=====
endif::exercise_solution[]
ifndef::exercise_solution[]
{nbsp}
. Aktualisieren Sie den Bonus von Angestellter mit der persnr. 5000 auf 100.
ifdef::exercise_solution[]
+
{nbsp}
{nbsp}
endif::exercise_solution[]
=====
.[#postgraphile-]#Q{counter:query_number}: Aktualisieren Sie den Bonus von Angestellter mit der `persnr=5000` auf 100.#
{sp}
[example,title=""]
=====
.Bonus eines Angestellten aktualisieren
ifdef::exercise_solution[]
[source%autofit,graphql]
----
mutation {
...
...
@@ -294,7 +359,17 @@ mutation {
}
}
----
endif::exercise_solution[]
ifndef::exercise_solution[]
{nbsp}
{nbsp}
{nbsp}
endif::exercise_solution[]
.Resultat der Mutation
ifdef::exercise_solution[]
[source%autofit,json]
----
{
...
...
@@ -310,16 +385,24 @@ mutation {
}
}
----
=====
endif::exercise_solution[]
ifndef::exercise_solution[]
{nbsp}
{nbsp}
{nbsp}
endif::exercise_solution[]
=====
. Schreiben Sie eine Query, die alle Daten des Angestellten mit persnr. 5000 anzeigt.
.[#postgraphile-]#Q{counter:query_number}: Schreiben Sie eine Query, die alle Daten des Angestellten mit `persnr=5000` anzeigt.#
{sp}
Damit überprüfen wir was in der Datenbank wirklich abgespeichert wurde.
ifdef::exercise_solution[]
+
[example,title=""]
=====
.Anzeigen der Daten des neuen Angestellten
ifdef::exercise_solution[]
[source%autofit,graphql]
----
{
...
...
@@ -337,7 +420,17 @@ ifdef::exercise_solution[]
}
}
----
endif::exercise_solution[]
ifndef::exercise_solution[]
{nbsp}
{nbsp}
{nbsp}
endif::exercise_solution[]
.Resultat
ifdef::exercise_solution[]
[source%autofit,json]
----
{
...
...
@@ -357,15 +450,23 @@ ifdef::exercise_solution[]
}
}
----
=====
endif::exercise_solution[]
ifndef::exercise_solution[]
{nbsp}
. Löschen Sie den Angestellten mit der persnr. 5000 wieder.
ifdef::exercise_solution[]
+
{nbsp}
{nbsp}
endif::exercise_solution[]
=====
.[#postgraphile-]#Q{counter:query_number}: Löschen Sie den Angestellten mit der `persnr=5000` wieder.#
{sp}
[example,title=""]
=====
.Löschen des Angestellten mit `persnr=5000`
ifdef::exercise_solution[]
[source%autofit,graphql]
----
mutation {
...
...
@@ -380,7 +481,17 @@ mutation {
}
}
----
endif::exercise_solution[]
ifndef::exercise_solution[]
{nbsp}
{nbsp}
{nbsp}
endif::exercise_solution[]
.Resultat der Löschung
ifdef::exercise_solution[]
[source%autofit,json]
----
{
...
...
@@ -395,8 +506,16 @@ mutation {
}
}
----
=====
endif::exercise_solution[]
ifndef::exercise_solution[]
{nbsp}
{nbsp}
{nbsp}
endif::exercise_solution[]
=====
{blank}
////
...
...
@@ -479,12 +598,12 @@ $$;
<1> Dieser Zusatz ist gemäss https://www.graphile.org/postgraphile/computed-columns/[Computed Column Konvention] notwendig!
=====
. Geben Sie alle Angestellten mit ihrem Wohnort aus, wobei der Wohnort als GeoJSON ausgegeben werden soll.
ifdef::exercise_solution[]
+
.[#postgraphile-]#Q{counter:query_number}: Geben Sie alle Angestellten mit ihrem Wohnort aus, wobei der Wohnort als *GeoJSON* ausgegeben werden soll.#
* APIs strukturell gleich und daher einfach zu benutzen
=====
endif::exercise_solution[]
Nachteile:::
ifndef::exercise_solution[]
+
[source,subs="post_replacements"]
----
+
----
{nbsp}
{nbsp}
endif::exercise_solution[]
ifdef::exercise_solution[]
=====
Nachteile:::
+
[example,title=""]
=====
ifdef::exercise_solution[]
* Viele Roundtrips notwendig um Daten abzufragen (N+1-Problem)
* Resultat enthält z.T. unnötigerweise alle Objekte und de Objekte enthalten immer alle Felder
=====
endif::exercise_solution[]
GraphQL::
Vorteile:::
ifndef::exercise_solution[]
+
[source,subs="post_replacements"]
----
+
----
{nbsp}
{nbsp}
endif::exercise_solution[]
ifdef::exercise_solution[]
=====
GraphQL::
Vorteile:::
+
[example,title=""]
=====
ifdef::exercise_solution[]
* Sämtliche benötigten Daten werden in einem "Roundtrip" geliefert.
* Die vom Client definierte Datenstruktur ist deklarativ und typisiert.
* Der Client ist vom Server entkoppelt; der Client definiert die verlangten Daten und nicht der Server.
=====
endif::exercise_solution[]
Nachteile:::
ifndef::exercise_solution[]
+
[source,subs="post_replacements"]
----
+
----
{nbsp}
{nbsp}
endif::exercise_solution[]
ifdef::exercise_solution[]
=====
Nachteile:::
+
[example,title=""]
=====
ifdef::exercise_solution[]
* Abfragesprache ist nur teilweise normiert, Grundelemente meist gleich
* Erweiterungen wie bspw. Filters sind Backend-spezifisch
=====
endif::exercise_solution[]
ifndef::exercise_solution[]
{nbsp}
{nbsp}
endif::exercise_solution[]
=====
. Nennen Sie je ein Beispiel für einen typischen Anwendungsfall von
+
SQL::
ifndef::exercise_solution[]
+
[source,subs="post_replacements"]
----
+
----
endif::exercise_solution[]
ifdef::exercise_solution[]
+
[example,title=""]
=====
ifdef::exercise_solution[]
Generelle Abfragesprache, beliebige Applikation mit normalisierten Daten, z.B. Nutzerverwaltung von Firma.
=====
endif::exercise_solution[]
RESTful::
ifndef::exercise_solution[]
+
[source,subs="post_replacements"]
----
+
----
{nbsp}
{nbsp}
endif::exercise_solution[]
ifdef::exercise_solution[]
=====
RESTful::
+
[example,title=""]
=====
ifdef::exercise_solution[]
* Aplikation mit wenigen _Klassen_, welche oft mit allen Inhalten ausgeliefert werden, z.B. Twitter.
* REST ist kein Standard, eher statisch, hat keine expliziten Joins ist dadurch aber auch viel einfacher.
=====
endif::exercise_solution[]
GraphQL::
ifndef::exercise_solution[]
+
[source,subs="post_replacements"]
----
+
----
{nbsp}
{nbsp}
endif::exercise_solution[]
ifdef::exercise_solution[]
=====
GraphQL::
+
[example,title=""]
=====
ifdef::exercise_solution[]
* Webapplikation mit Joins/diversen verknüpften Daten, von welchen man meist nicht alle Felder braucht, z.B. Frontend für die Nutzerverwaltung einer Firma.
* GraphQL ist Web-orientiert, dynamisch (Standard lässt absichtlich vieles Offen) und einfach zu verwenden.