GraphQL – Die Alternative zu REST

Teil 1: Übersicht und Backend

Was ist GraphQL?

GraphQL ist eine Abfragesprache für APIs zur Ausführung von Abfragen mit Hilfe eines für die Daten definierten Typensystems. GraphQL ist nicht an eine bestimmte Datenbank gebunden (https://graphql.org/learn/)

GraphQL vs. REST

GraphQL bietet die Möglichkeit, Daten über HTTP zu senden. Jede Anfrage in GraphQL ist eine POST-Anfrage. Der Body enthält die Abfrage für den Server, welcher die Abfrage auflöst. Um Daten zu erhalten, wird eine Query gesendet. Wenn man Daten erstellen, ändern oder löschen möchte, wird eine Mutation gesendet.
GraphQL ist eine flexible Abfragesprache für APIs. Es ermöglicht Entwicklern, genau die Daten zu erhalten, die sie benötigen.

Vor- und Nachteile von GraphQL

Pro:

  • Schnelle Prototypenentwicklung
  • API-Erweiterung ohne Versionierung
  • Autogenerierte API-Dokumentation mit GraphiQL
  • Es werden immer die Daten geholt, die benötigt werden
  • Loose coupling zwischen Server und Client

Contra:

  • Keine simple Caching-Strategie
  • Overkill für kleine Anwendungen
  • File-Upload nicht möglich
  • Komplex beim Einstieg
  • Performanceprobleme bei tief verschachtelten Abfragen

GraphQL 101

In dieser kleinen Blog-Serie schauen wir uns einfache Queries und Mutations an. Wir haben eine kleine Testanwendung mit Adressen und Benutzern, diese stehen in einer 1-zu-1 Beziehung zueinander. Die Anwendung wurde mit folgender Technologie umgesetzt:

  • .NET Core 2.2
  • Entity Framework Core
  • GraphQL for .NET (https://graphql-dotnet.github.io/)
  • GraphiQL (https://github.com/graphql/graphiql)
  • Angular

Query

Die einfachste Art eine Query zu beschreiben ist es, diese mit einem GET-Request à la REST zu vergleichen.

Abbildung 1: eine einfache Query in GraphiQL
Abbildung 1: eine einfache Query in GraphiQL

Mit dieser einfachen Query wird ein User mit den Eigenschaften firstName und lastName geladen. Hier sieht man bereits den Vorteil von GraphQL, dass das Ergebnis den gleichen Aufbau aufweist wie die Abfrage. Außerdem haben wir nur die Daten erhalten, die wir auch abgefragt haben.

Abbildung 2: User und Address Klasse mit Eigenschaften
Abbildung 2: User und Address Klasse mit Eigenschaften

Die Entität User hat mehr Eigenschaften als nur firstName und lastName:

Abbildung 3: Datenabfrage eines Users mit einer spezifischen Id
Abbildung 3: Datenabfrage eines Users mit einer spezifischen Id

In Abbildung 3 haben wir ein Beispiel einer Query mit einem Argument.

user(id:25)

  • user = Name der Query
  • id = Name des Arguments
  • 25 = Wert des Arguments

In GraphQL spricht man nicht von Parametern, sondern von Argumenten.

Außerdem zeigt dieses Beispiel die verschachtelte Abfrage der Address-Eigenschaften.

Mutation

Eine Mutation ist eine Unterart der Query. Damit werden, wie der Name schon vermuten lässt, Daten erstellt, geändert oder gelöscht.

Abbildung 4: Beispiel Mutation mit zwei Argumenten und dem Rückgabewert Id
Abbildung 4: Beispiel Mutation mit zwei Argumenten und dem Rückgabewert Id

In diesem Beispiel können wir eine weitere Eigenschaft von GraphQL Queries sehen: query variables. Darin werden komplexe Objekte eingetragen; in unserem Beispiel ein User und eine Address.

Jede Mutation beginnt mit dem Wort mutation,um diese Query als eine Mutation zu erkennen. Der Inhalt in der Klammer definiert Variablen und den entsprechenden Datentypen dazu. In unserem Beispiel entspricht die Variable $user einem UserInput.

Abbildung 5: UserInputType
Abbildung 5: UserInputType

Unsere UserInputType Klasse erbt von InputObjectGraphType<T> wobei T in unserem Beispiel die Entität User ist. Der Name entspricht dem Namen in Abbildung 4. Standardmäßig akzeptieren die Felder keine NULL-Werte. Mit einem false als zweiten Parameter, akzeptieren die Felder auch ein NULL als Wert.

Abbildung 6: Nullable Field
Abbildung 6: Nullable Field

Datentypen in GraphQL, GraphQL for .NET und .NET

Ein GraphQL-Objekttyp hat einen Namen und Felder, aber irgendwann müssen diese Felder in konkrete Daten umgewandelt werden. An dieser Stelle kommen die skalaren Typen ins Spiel.

In der Abbildung 7 sieht man die Typen, die von der GraphQL Specificiation bereitgestellt werden. Außerdem können wie im UserTypeInput-Beispiel eigene Typen erstellt werden.

Abbildung 7: Skalare Typen
Abbildung 7: Skalare Typen

Backend Struktur

Das Beispielprojekt ist in zwei Projekte aufgeteilt (das Testprojekt wird ignoriert). Das Data-Projekt enthält die Logik zum Lesen und Schreiben von Daten in die Datenbank mit Entity Framework. Das API-Projekt beinhaltet die interessante GraphQL-Logik. Aus Gründen der Einfachheit werden wir auch das Data-Projekt ignorieren.

Abbildung 8: Projekt Struktur
Abbildung 8: Projekt Struktur

Wir legen den Fokus auf folgende Klassen:

  • GraphQuery
  • AppSchema
  • AppQuery
  • AppMutation
  • UserType und AddressType
  • UserInputType und AddressInputType
  • ContextServiceLocator
  • GraphQlController

GraphQuery.cs

Die GraphQuery Klasse beinhaltet die Definition, welche Eigenschaften eine Query haben kann.

Abbildung 9: GraphQuery.cs
Abbildung 9: GraphQuery.cs

In unserem Beispiel hat unsere Klasse zwei Eigenschaften:

  • Query – die Query selbst
  • Variables – die Variablen, die mit der Query mitgesendet werden

AppSchema

Das AppSchema beschreibt die möglichen Queries und Mutations. Außerdem löst der IDependencyResolver, eine Komponente der GraphQL for .NET Library, die Abhängigkeiten auf.

Abbildung 10: AppSchema
Abbildung 10: AppSchema

AppQuery

Diese Klasse enthält die Definitionen darüber, wie die Daten abgefragt werden können. Eine GraphQL Query wird als Field bezeichnet. Jedes Field ist einem Typen zugeordnet und hat folgende Parameter:

  • name : String – der Name der Query
  • arguments : QueryArguments – Liste mit Argumenten vom Typ QueryArgument<T>, wobei T ein ObjectGraphType ist
  • resolve : ResolveContextField – hier wird definiert, was getan werden muss, um die Daten zu bekommen. Außerdem muss hier ein dem Field entsprechender Rückgabewert definiert werden
Abbildung 11: AppQuery
Abbildung 11: AppQuery

AppMutation

Eine Mutation ist genauso aufgebaut wie eine Query, mit der Ausnahme, dass die Eigenschaft Name gesetzt werden muss.

Abbildung 12: Ausschnitt Mutation
Abbildung 12: Ausschnitt Mutation

UserType und AddressType

Diese Klassen erben von der Klasse ObjectGraphType. Dadurch können Objekte dieser Klasse in Feldern von Queries und Mutations vorkommen. In unserem Beispiel erben wir von einer konkreteren Klasse, und zwar ObjectGraphType<T>, wobei T einmal User und einmal Address ist. Dadurch können wir die Field-Eigenschaft einfacher mit den Eigenschaften der entsprechenden Entität zusammenführen. Standardmäßig werden hier keine NULL-Werte erlaubt. Mit dem optionalen Parameter true als zweiten Übergabeparameter kann man dennoch NULL-Werte zulassen. Durch einen Namen kann der Type einfacher in der GUI von GraphiQL erkannt werden.

Abbildung 13: Eigene Definitionen von ObjectGraphType
Abbildung 13: Eigene Definitionen von ObjectGraphType

UserInputType und AddressInputType

Um Mutations mit ganzen Objekten zu erstellen, werden InputTypes benötigt. Die Klassen der InputTypes erben von InputObjectGraphType<T>. Auch hier kann T wieder einer Entität entsprechen, um die Eigenschaften einfacher zu definieren.

Abbildung 14: UserInput- und AddressInputType
Abbildung 14: UserInput- und AddressInputType

ContextServiceLocator

Diese praktische Klasse dient als Hilfe für unsere AppQuery und AppMutation-Klasse, um die entsprechenden Repositories zu laden.

Abbildung 15: ContextServiceLocator
Abbildung 15: ContextServiceLocator

GraphQlController

Für eine GraphQL Anwendung wird nur ein Controller benötigt. Das heißt natürlich nicht, dass man nicht mehrere Controller verwenden darf. Bei mehreren AppSchema Klassen kann es sehr nützlich sein, auch mehrere Controller zu haben. Durch constructor dependency injection wird das AppSchema und die Komponente IDocumentExecuter bereitgestellt. Der IDocumentExecuter ruft die entsprechende Query oder Mutation auf.

Abbildung 16: GraphQLController
Abbildung 16: GraphQLController

Fazit

GraphQL ist der Traum jedes Frontend-Entwicklers. Keine Daten fehlen in der Anfrage und es werden auch nicht zu viele gesendet. Leider wird in diesem Beispiel das sogenannte “under/overfetching”-Problem nach hinten verschoben, zwischen Backend und Datenbank, da Entity Framework alle Eigenschaften mit lädt. Das Gerüst zu bauen – mit allen Queries und Mutations – kann durchaus mehr Zeit in Anspruch nehmen, als vielleicht zuerst erwartet. Wenn diese initiale Arbeit aber erstmal geleistet worden ist, ist es sehr effizient an einer GraphQL Anwendung zu arbeiten. Wenn am Datenmodel nicht mehr gearbeitet wird, kann jeder Frontend-Entwickler sich die Daten so holen, wie es für seine Plattform am besten ist. 

Mehr Blogposts

Microsoft Teams SPFx
Blog
Blog

Microsoft Teams SPFx

Die bisherige Entwicklung von Teams Applikation gestaltete sich zuvor wie die Entwicklung einer Webseite, welche dann einfach per Manifest in Teams eingebunden ...

Umfragen in Teams mit Microsoft Forms
Blog
Blog

Umfragen in Teams mit Microsoft Forms

Umfragen bieten die Möglichkeit, bei der Planung von beispielsweise Events schnell zu einem Termin/Ergebnis zu kommen oder aber auch Feedback zu vergangenen Ere...

PDF-Konverter in Power Automate
Blog
Blog

PDF-Konverter in Power Automate

Kann ich mittels Microsoft Power Automate und einer SPFx-Anwendung ohne größere Probleme einen PDF-Konverter erstellen? Die einfache Antwort: Ja. Und auch die A...

6 Tipps für bessere Web-Meetings
Blog
Blog

6 Tipps für bessere Web-Meetings

Unsere Arbeitswelt steht Kopf: Da jede Art persönlicher Termine nicht mehr stattfindet, wird auf Videokonferenzen via Teams oder Zoom ausgewichen. Nicht wenige ...

Migration SharePoint 2013 zu 2019
Blog
Blog

Migration SharePoint 2013 zu 2019

Auch wenn die Cloud und allen voran O365 von vielen Unternehmen forciert wird, gibt es immer noch viele Organisationen, wie beispielsweise Banken und Behörden, ...

pnpm: eine Alternative zu npm
Blog
Blog

pnpm: eine Alternative zu npm

pnpm ist eine Alternative zu den Paket-Managern npm oder yarn. Wie bei diesen Anbietern werden von pnpm die verwendeten Pakete von der npm-Registry gezogen. Der...

Testen von Angular Anwendungen mit Cypress
Blog
Blog

Testen von Angular Anwendungen mit Cypress

Cypress ist ein End-to-End Testing Framework, mit dem man einfache Tests erstellen kann, die in Echtzeit ausgeführt werden. Mit Cypress kann man auch Snapshots ...

Anhänge nach Datentyp in PowerApps einschränken
Blog
Blog

Anhänge nach Datentyp in PowerApps einschränken

Eine immer wieder auftauchende Anfrage bei digitalen Prozessen ist die Beschränkbarkeit von Anhangsdokumenten. Glücklicherweise lässt sich diese Funktionalität ...

Cloud Metadaten
Drei Tipps für mehr SharePoint-Begeisterung
Blog
Blog

Drei Tipps für mehr SharePoint-Begeisterung

Wir geben Tipps zur der Microsoft Serverplattform für Content Management, (Social)-Collaboration, Portalfunktion, Business Intelligence und Enterprise Search.

Azure Functions: Der Webservice ohne Webserver
Blog
Blog

Azure Functions: Der Webservice ohne Webserver

Azure Functions als Authentifizierungs-Helfer für clientseitige Lösungen mit 3rd Party APIs

Teams Extensions – Erstellen von Erweiterungen für Teams
Blog
Blog

Teams Extensions – Erstellen von Erweiterungen für Teams

Mit der Entwicklung von Extensions kann Teams einfach erweitert werden. Hierfür gibt es das App Studio, welches über den Teams Store installiert werden kann.

.NET-Anwendung hinter Proxy-Servern, Kommunikation mit Azure
Blog
Blog

.NET-Anwendung hinter Proxy-Servern, Kommunikation mit Azure

Praktische Beispiele für die Anwendung von Proxy-Servern bei .NET-Apps und -Websites sowie die Kommunikation über den Azure Service Bus.

DevOps und „The Phoenix Project“
Blog
Blog

DevOps und „The Phoenix Project“

Buchvorstellung "Projekt Phoenix: Der Roman über IT und DevOps - Neue Erfolgsstrategien für Ihre Firma" von Gene Kim.

Ich bin im Flow! – Eine Übersicht zu Microsoft Flow
Blog
Blog

Ich bin im Flow! – Eine Übersicht zu Microsoft Flow

Die Power Platform wird aktuell von Microsoft sehr stark gepusht. Zeit, sich mit dem Potenzial der einzelnen Komponenten zu beschäftigen. Heute: Flow.

DevOps und Container
Blog
Blog

DevOps und Container

DevOps an sich ist nicht an eine Technologie gebunden, jedoch haben sich Container-Technologien und DevOps als Verwandte im Geiste gefunden.

Paket Dependency Manager für .NET
Blog
Blog

Paket Dependency Manager für .NET

Paket ist ein Dependency Manager für .NET, welcher es sich zum Ziel gesetzt hat einige Probleme von NuGet zu beheben.

Tipps und Tricks mit Entity Framework
Blog
Blog

Tipps und Tricks mit Entity Framework

In diesem Blogbeitrag möchte ich einige Tipps und Tricks rund um Entity Framework mit euch teilen. In allen Beispielen gehen wir vom Code-First Ansatz aus.

SharePoint Framework Client-Side Webparts mit React
Blog
Blog

SharePoint Framework Client-Side Webparts mit React

React ist ein Framework zur Erstellen von Benutzeroberflächen. In der SharePoint Online Entwicklung bietet es sich für die Entwicklung von Client-Side Webparts...

Sprechen Sie LUIS? – Der intelligente Chat-Bot im Praxistest
Blog
Blog

Sprechen Sie LUIS? – Der intelligente Chat-Bot im Praxistest

Mit LUIS, der Sprach- und Texterkennungssoftware von Microsoft, und dem Bot Framework von Azure haben wir eine Lösung für den IT-Support entwickelt.

Grundlagen der Gestaltung
Blog
Blog

Grundlagen der Gestaltung

Die Gestaltgesetze der Wahrnehmungspsychologie

PowerApps – Neuigkeiten, Übersicht, Tipps & Tricks
Blog
Blog

PowerApps – Neuigkeiten, Übersicht, Tipps & Tricks

Neues aus der Welt von PowerApps

Cloud Metadaten
SharePoint Suche – FirstSpirit Website Crawl
Blog
Blog

SharePoint Suche – FirstSpirit Website Crawl

Die Einbindung von Inhaltsquellen in die SharePoint Enterprise Suche kann den Administrator vor unvorhersehbare Herausforderungen stellen. Tipps dazu.

Microservices automatisiert in Azure betreiben
Blog
Blog

Microservices automatisiert in Azure betreiben

VSTS, Docker Swarm Mode, Traefik und Azure IaaS

Zentralisiertes Logging – Simpler Logging-Stack mit Graylog
Blog
Blog

Zentralisiertes Logging – Simpler Logging-Stack mit Graylog

Logging ist ein komplexes und doch essenzielles Thema. Gute Logs vereinfachen einem Supporter die Arbeit und ermöglichen es, Probleme schneller einzugrenzen.

Lasttests für Microsoft SharePoint 2013/2016
Blog
Blog

Lasttests für Microsoft SharePoint 2013/2016

Der Artikel beschreibt eine einfache Methode zur Durchführung von Belastungstests mit Hilfe des Webserver Stress Tools des deutschen Unternehmens Paessler.

Cloud Metadaten
Nutzung der SharePoint REST API mit Microsoft Flow
Blog
Blog

Nutzung der SharePoint REST API mit Microsoft Flow

Durch Zugriffe über die REST API lassen sich viele Vorgänge mit Microsoft Flow automatisieren.

Traceability in agilen Projekten – RTM im Jahr 2018
Blog
Blog

Traceability in agilen Projekten – RTM im Jahr 2018

Ein wichtiges Ergebnis des Requirements Engineering in einem Wasserfallprojekt ist die Traceability Matrix. Sie bildet das Bindeglied zwischen den Anforderungen...

Angular Route-Guards
Blog
Blog

Angular Route-Guards

Was versteht man eigentlich unter Angular Route-Guards?

Cloud Metadaten
Spaltenformatierung in SharePoint: Column formatting vs. JS
Blog
Blog

Spaltenformatierung in SharePoint: Column formatting vs. JS

Eine Gegenüberstellung der Spaltenformatierung von JSLink zu der neueren Methode Column formating in Office 365.

Struktureller Aufbau eines Angular Modules
Blog
Blog

Struktureller Aufbau eines Angular Modules

Dieser Blogbeitrag beschäftigt sich mit dem strukturellen Aufbau eines Angular Modules und der Kommunikation der einzelnen Komponenten.

Hub Sites – Neues Level der Vernetzung
Blog
Blog

Hub Sites – Neues Level der Vernetzung

Mit der Einführung der Modern Sites auf SharePoint Online hielt ein komplett neues Bedienungs-, Oberflächen- und Nutzungskonzept Einzug. Microsoft führt diese O...

Cloud Metadaten
Hybride Metadaten und Inhaltstypen
Blog
Blog

Hybride Metadaten und Inhaltstypen

Dies sollten Sie bei der Verwaltung von Metadaten in hybriden SharePoint-Umgebungen beachten, um eine reibungslose Synchronisation zu sichern.

Entwicklung von Webparts mit SharePoint Framework
Blog
Blog

Entwicklung von Webparts mit SharePoint Framework

Teil 1 – Solution Struktur

Sliding to heaven – A short story of a SPFx Slider Webpart
Blog
Blog

Sliding to heaven – A short story of a SPFx Slider Webpart

SharePoint Framework, kurz SPFx, ist eine zukunftsträchtige Technologie zur Erstellung von Webparts oder Extensions auf der Basis von TypeScript.

Angular 5 Custom Filter in Angular Material Data-Table
Blog
Blog

Angular 5 Custom Filter in Angular Material Data-Table

In diesem Blogbeitrag will ich euch darlegen, wie man einen Custom Filter für das Angular Material Data-Table Modul erstellt.

Grundlagen der Datenmodellierung – Teil 1
Blog
Blog

Grundlagen der Datenmodellierung – Teil 1

Fachliches Modell mit ER-Diagrammen (auch ERM – Entity Relationship Model)

Aus Zwei mach Eins – Das kann das neue Sharegate Update
Blog
Blog

Aus Zwei mach Eins – Das kann das neue Sharegate Update

In diesem Beitrag zu Sharegate gebe ich Einblicke in die Neuerungen und Veränderungen als auch persönlichen Erfahrungen weiter.

PayPal-Zahlung in einer MVC Anwendung
Blog
Blog

PayPal-Zahlung in einer MVC Anwendung

In diesem Blogbeitrag möchte ich demonstrieren, wie eine Einbindung von PayPal in eine MVC Applikation funktioniert.

Der wiederholte Bereich in Nintex Forms
Blog
Blog

Der wiederholte Bereich in Nintex Forms

Nintex für Fortgeschrittene

HoloLens Hackathon
Blog
Blog

HoloLens Hackathon

Virtual-, Augmented- und Mixed Reality sind Begriffe, die man evtl. schon einmal gehört oder indirekt damit zu tun gehabt hat. Doch was steckt dahinter?

Part 2 – Alexa Custom Skill: Azure Function
Blog
Blog

Part 2 – Alexa Custom Skill: Azure Function

In diesem Blogbeitrag geht es um die von Alexa gesendeten Anfragen, Anfragen an SharePoint Online sowie die Verarbeitung dieser mithilfe von C#.

Part 1 – Alexa Custom Skill: Amazon
Blog
Blog

Part 1 – Alexa Custom Skill: Amazon

In diesem Beitrag liegt der Schwerpunkt vor allem auf dem Erstellen eines Custom Skills im Amazon Developer Portal, dem Anlegen eines Interaction Models und der...

Cloud Metadaten
SharePoint-Migration unter Einhaltung der BITV 2
Blog
Blog

SharePoint-Migration unter Einhaltung der BITV 2

Einhaltung aller Vorgaben durch die BITV 2 bei einer Migration von SharePoint Server 2013 zu 2016.

Cloud Metadaten
Real-time Web mit SharePoint (SignalR)
Blog
Blog

Real-time Web mit SharePoint (SignalR)

Was ist Real-time Web?

Handlebars.js – Semantische Template Library
Blog
Blog

Handlebars.js – Semantische Template Library

Handlebars.js ist eine Template-Engine für JavaScript. Sie ermöglicht dem Entwickler, mit Hilfe von semantischen Templates Business-Logik und HTML zu trennen.

Cloud Metadaten
SPFx: Lohnt der Einsatz des SharePoint-Frameworks?
Blog
Blog

SPFx: Lohnt der Einsatz des SharePoint-Frameworks?

Im Rahmen der Planung von Lösungen für Unternehmen mit Bezug auf das SharePoint-Framework sollte man klären: Lohnt es sich, SPFx bereits produktiv einzusetzen?

SharePoint vs. TYPO3 – Sechs Gründe für SharePoint-Intranet
Blog
Blog

SharePoint vs. TYPO3 – Sechs Gründe für SharePoint-Intranet

Hier lesen Sie die sechs wichtigsten Argumente, warum Sie Office 365 mit SharePoint für Ihre Intranetlösung gegenüber TYPO3 bevorzugen sollten.

Corporate News – Das zentrale Medium interner Kommunikation
Blog
Blog

Corporate News – Das zentrale Medium interner Kommunikation

Um die Akzeptanz des unternehmenseigenen Intranets zu steigern, sind Corporate News ein erster Schritt, um Neuigkeiten, Strategie und Strukturen gleichmäßig zu ...

Entwicklung mit Xamarin – Quick Start
Blog
Blog

Entwicklung mit Xamarin – Quick Start

Xamarin ermöglicht die Entwicklung von nativen mobilen Applikationen mit Hilfe einer gemeinsamen Codebasis.

Cloud Metadaten
SharePoint Hosted Add-in mit AngularJS 2
Blog
Blog

SharePoint Hosted Add-in mit AngularJS 2

Voraussetzungen und Umsetzung eines SharePoint Hosted Add-in mit AngularJS 2.