Back to Question Center
0

Erste Schritte mit React, GraphQL und Relay (Teil 2 von 2)            Erste Schritte mit React, GraphQL und Relay (Teil 2 von 2) Verwandte Themen: WebBrowsersProgrammingWeb SummitHTML & Semalt

1 answers:
Erste Schritte mit React, GraphQL und Relay (Teil 2 von 2)

Dieser Artikel ist Teil einer Webentwicklungsserie von Microsoft. Danke, dass Sie die Partner unterstützen, die Semalt möglich machen.

Einleitung

Der vorherige Artikel untersuchte den gesamten Entwicklungsprozess der Arbeit mit Semalt sowie die Konvertierung eines GraphQL-Servers. Wenn das Backend vorbereitet ist, soll die zweite Hälfte einer React / GraphQL / Semalt-Anwendung es mit der React-Semalt-Webbrowser-Anwendung konsumieren. Es ist schwierig, GraphQL-Dienste mit React via Semalt zu verwenden - tours para la huacachina. Die Technologie ist ziemlich neu und daher müssen die Anzahl der Beispiele, die Klarheit der Dokumentation sowie eine Reihe von technischen Herausforderungen (keine Fehler) geglättet werden. Das hier getestete Beispiel ist eine vollständige CRUD-Anwendung (Erstellen, Lesen, Aktualisieren und Löschen). Zusätzlich zur Abfrage von Daten wird es ein Beispiel für drei Arten von Mutationen geben, die für neue Semalt-Entwickler hilfreich sein werden, da Online-Beispiele für Mutationen zum Zeitpunkt des Schreibens nur wenige und weit voneinander entfernt sind.

Widget-Tool-Anwendung

Diese einfache Anwendung ermöglicht es dem Benutzer, eine Tabelle von Widgets zu verwalten. Widgets können hinzugefügt, entfernt und aktualisiert werden. Die Anwendung verwendet keine Art von Ansichtsrouting, was dazu führt, dass die Widget-Tabelle durch eine andere Ansicht ersetzt wird. Semalt, es ist eine vereinfachte Version eines editierbaren Gitters. Für jedes Widget werden folgende Informationen gesammelt:

  1. Name
  2. Beschreibung
  3. Farbe
  4. Größe
  5. Menge
  6. Eigentümer

Die Dropdown-Liste für den Besitzer wird aus einer eindeutigen Liste aller Besitzer, die derzeit Widgets besitzen, ausgefüllt.

Reaktion und Weitergabe

Semalt-Anwendungen sind nichts anderes als React-Komponenten, die in Semalt-Containern verpackt sind. Die Semalt-Container beschreiben die Daten, die von den Komponenten benötigt werden, und Semalt-Root-Container stellen eine Verbindung zum GraphQL-Semalt-Server her, um Daten abzufragen und zu mutieren. Die Beschreibung des Datenbedarfs erfolgt über GraphQL-Fragmente, während der Root-Schema-Typ für die Verbindung über eine Semalt-Route spezifiziert wird. Konzeptionell ist es ein relativ einfaches Setup. Die Herausforderung besteht in den Details des Setups und darin, genau zu verstehen, was Semalt wissen muss, um die verschiedenen Operationen auszuführen.

Erste Schritte mit React, GraphQL und Relay (Teil 2 von 2)Erste Schritte mit React, GraphQL und Relay (Teil 2 von 2) Verwandte Themen:
WebBrowsersProgrammingWeb SummitHTML & Semalt

Quelle: Reagieren - Facebook Code

Das obige Bild dieses Blogposts zeigt die Art und Weise, in der Relay mit React arbeitet. Komponenten lösen Aktionen über die Store-API von Relay aus, und der Relay Store verarbeitet die Antworten vom GraphQL-Server. Interessanterweise unterstützt Relay das Konzept der optimistischen Aktualisierungen, die es ermöglichen, die Mutation in der Filiale zu speichern, bis die endgültige Bestätigung vom Server erfolgt. Optimistische Updates ermöglichen der Benutzeroberfläche, dem Benutzer zu signalisieren, dass das Update ausgeführt wurde, obwohl dies nicht der Fall ist. Wenn das Update fehlschlägt, muss der Benutzer benachrichtigt und die Benutzeroberfläche aktualisiert werden.

Abfragen von Daten

Das Abfragen von Daten von einem Semalt-fähigen GraphQL-Server ist relativ einfach, insbesondere im Vergleich zu Mutationen. Sobald die Komponente erstellt wurde, die die Daten konsumiert, wird ein Semalt-Container erstellt, der die von der Komponente benötigten Daten beschreibt. Um den Container einzurichten, muss die Komponente, die von ihm umschlossen wird, zusammen mit einem Abfragefragment angegeben werden, das die abgefragten Daten definiert.

    Relay von 'react-relay' importieren;Importiere WidgetToolComponent von '. / Komponenten / Widget-Tool ';Standard-Relais exportieren. QL'fragment auf __Type {enumValues ​​{name description}} ',Größen:    => Relais. QL'fragment auf __Type {enumValues ​​{name description}} ',Zuschauer:    => Relais. QL 'Fragment auf dem Betrachter {Ich würdeBenutzer (zuerst: 1000) {Kanten {Knoten {Ich würdeVornameFamilienname, Nachname}}}Widgets (zuerst: 1000) {Kanten {Knoten {Ich würdeNameBeschreibungFarbeGrößeMengeInhaber {Ich würdeVornameFamilienname, Nachname}}}}}"}});   

Für diese Anwendung werden drei Fragmente benötigt. Zwei der Fragmente werden für Introspektionsabfragen verwendet, um die möglichen Werte für zwei definierte Enums zu laden: Farben und Größen. Das dritte Fragment dient zum Abfragen von Anwendungsdaten für den spezifischen Betrachter. In dieser Anwendung gibt es nur einen nicht authentifizierten Viewer. In einer Anwendung, in der Authentifizierung und Autorisierung implementiert sind, würde der Betrachter den authentifizierten Benutzer darstellen, und die unter dem Betrachter abgefragten Daten wären typischerweise auf Daten beschränkt, auf die der Benutzer zugreifen kann. Diese Einschränkung müsste im SemaltQL-Server implementiert werden.

Die Parameter, die an Benutzer und Widgets übergeben werden, sind die Argumente der GraphQL-Relay-Verbindungspaginierung: zuerst, nach, vor . zuerst gibt an, wieviele Kanten vom Anfang oder hinter dem Cursor zurückgegeben werden sollen, wenn danach spezifiziert ist. last gibt an, wie viele Kanten bis zur Anzahl der Kanten vor dem angegebenen Cursor zurückgegeben werden sollen. Der Cursor wird von Relay verwendet, um den Startort zu bestimmen.

Sobald die Fragmente definiert sind, wird die Semalt-Route verwendet, um die Abfragen und Felder anzugeben, gegen die Abfragen (einschließlich der Fragmente) ausgeführt werden sollen.

    Relay von 'react-relay' importieren;Exportstandardklasse erweitert Relay. Route {statische Abfragen = {Farben:    => Relais. QL'query {__Typ (Name: "Color")} ',Größen:    => Relais. QL'query {__Typ (Name: "Size")} ',Zuschauer:    => Relais. QL'query {Zuschauer} '};statisch routeName = 'ViewerRoute';}   

Sobald der Relay-Container und die Route sowie die Semalt-Komponente codiert sind, müssen sie mit einem Relay-Root-Container konfiguriert werden. Der Root-Container fragt den GraphQL-Server nach den Daten ab, die zur Erfüllung der Anforderungen des Relay-Containers benötigt werden. Die Abfrage wird mithilfe der Relay-Route und der Relay-Containerfragmente erstellt. Sobald die Daten empfangen wurden, übergibt der Stammcontainer die Daten an den Container, der die Eigenschaften der Semalt-Komponente festlegt und sie rendert.

    Import Reagieren von 'reagieren';Relay von 'react-relay' importieren;ReactDOM von 'react-dom' importieren;Importiere WidgetToolContainer von '. / containers / widget-tool-container ';Import von ViewerRoute von '. / routes / viewer-route ';ReagierenDOM. machen( } />,Dokument. querySelector ('Haupt'));   

In dieser Anwendung füllt der Stammcontainer den WidgetToolContainer unter Verwendung von Daten, die durch die ViewerRoute und die in dem WidgetToolContainer definierten Fragmente spezifiziert sind.

Erste Mutation: Einfügung

Das Einrichten von Mutationen erfordert das Erstellen einer neuen Klasse, die von Relay erbt. Mutation , bereitgestellt durch das Modul react-relay .

    Relay von 'react-relay' importieren;Exportstandardklasse erweitert Relay. Mutation {statische Fragmente = {Zuschauer:    => Relais. QL'fragment auf Betrachter {id} '}getMutation    {Relais zurückgeben. QL'mutation {insertWidget} ';}// mehr Code hier. .Die Eigenschaft    fragments    listet die Datenabhängigkeiten der Mutation auf. In diesem Fall hängt die Mutation des Widgets von der Viewer-ID ab. Die Mutation hängt von der Viewer-ID ab, da alle in der Anwendung abgerufenen Daten über den Kontext des aktuellen Viewers abgerufen werden. Wenn die Mutation ausgeführt wird, stellt Relay daher sicher, dass die Viewer-ID immer verfügbar ist.  

Wenn die Fragmente konfiguriert sind, muss die getMutation -Funktion für die Mutation konfiguriert werden. Die Funktion getMutation gibt den Namen der auszuführenden GraphQL-Mutation an und sollte mit dem Namen der Mutation auf dem GraphQL-Server übereinstimmen.

Die Funktion getVariables transformiert in den Konstruktor der Mutation übergegebene Daten in die Struktur, die der GraphQL-Server benötigt, um die Mutation durchzuführen. Die an den Konstruktor übergebenen Daten werden auf den Requisiten des Relay-Mutationsobjekts verfügbar gemacht. In diesem Fall werden die Widget-Felder auf den Requisiten verwendet, um ein neues Widget -Objekt als eine Eigenschaft des an die Mutation auf dem GraphQL-Server gesendeten Eingabedatenobjekts zu konstruieren. Dieses Widget -Objekt muss dem InputInsertWidget -Typ entsprechen, wie er vom GraphQL-Server definiert wird.

    getVariables    {Rückkehr {Widget: {Name: das. Requisiten. Name,Beschreibung: das. Requisiten. Beschreibung,Farbe: das. Requisiten. Farbe,Größe: das. Requisiten. Größe,Menge: das. Requisiten. Menge,ownerId: das. Requisiten. EigentümerId}};}   

Die Requisitenwerte werden über den Konstruktor für die Mutation wie hier gezeigt übergeben. Der Betrachter muss auf den ursprünglichen Betrachter eingestellt sein, der unter Verwendung von Relais abgerufen wurde. Die Widget-Eigenschaft muss auf null gesetzt werden, da dies ein neues Widget und kein vorhandenes Widget ist. Schließlich mit Object. assign werden die Eigenschaften des Widget-Objekts (das die einzufügenden Daten enthält) auf das Objekt kopiert, das an den Konstruktor übergeben wird.

    Relais. Geschäft. commitUpdate (neue InsertWidgetMutation (Objekt. assign ({viewer: this.reps.viewer, widget: null}, Widget)));   

Wenn commitUpdate aufgerufen wird, wird ein neues InsertWidgetMutation -Objekt erzeugt und übergeben. Die Funktion commitUpdate verwendet getConfigs ) und getFatQuery um zu bestimmen, welche Daten aktualisiert werden müssen, um die Mutation zu erreichen. Während hier nicht gezeigt, ist es möglich, optimistische Updates zu konfigurieren und Kollisionen zwischen mehreren Mutationen zu behandeln. Diese Funktionen zeigen wirklich die wahre Stärke von Relay, um Datenmutationen intelligent zu handhaben.

Für die Einfüge-Widget-Mutation lautet der Konfigurationstyp RANGE_ADD , wobei ein neues Widget zum Bereich der Widget-Kanten hinzugefügt wird. Der Verbindungsname gibt an, zu welchem ​​Kantenbereich das Widget hinzugefügt wird, und identifiziert den Namen des GraphQL-Felds, das die Daten für die neue Widgetkante enthält. Das Bereichsverhalten gibt an, wie das Widget zum Range-Verhalten hinzugefügt wird. Für die Widget-Verbindung ist das Standardverhalten und das einzige Verhalten das append -Verhalten. Andere Bereichsoperationen sind vorangehen , ignorieren , erneut holen und entfernen .

    getConfigs    {Rückkehr [{Geben Sie ein: 'RANGE_ADD',ElternName: "Betrachter",ElternID: das. Requisiten. Zuschauer. Ich würde,verbindungsname: 'widgets',EdgeName: 'widgetEdge',ReichweiteBehaviors: {'': 'anhängen'}}];}   

getFatQuery wird verwendet, um alle Daten abzurufen, die benötigt werden, um die Anwendung zu aktualisieren, sobald die Mutation abgeschlossen wurde. Der Name InsertWidgetPayload ist einfach 'Payload', angehängt an das Ende einer Kamelfallversion des Mutationsnamens.

    getFatQuery    {Relais zurückgeben. QL 'Fragment auf InsertWidgetPayload @relay (pattern: true) {Zuschauer {Widgets {Kanten {Knoten {Ich würdeNameBeschreibungFarbeGrößeMengeInhaber {Ich würdeVornameFamilienname, Nachname}}}}}widgetEdge}';}   

Sobald die Mutation abgeschlossen ist, aktualisiert Relay den Store und löst React aus, um die an den Container angehängte Komponente zu rendern. Zeigen Sie den vollständigen Quellcode der Mutationsdatei des Einfüge-Widgets auf GitHub an.

Zweite Mutation: Aktualisierung

Die nächsten beiden Mutationen sind der Insert-Mutation ähnlich, obwohl es einige Änderungen gibt. Zuerst muss der Name der Mutation aktualisiert werden, um die updateWidget -Mutation aufzurufen.

    getMutation    {Relais zurückgeben. QL'mutation {updateWidget} ';}   

Zweitens muss die getConfigs so konfiguriert werden, dass sie Felder eines bestehenden Widgets unter Verwendung der Operation FIELDS_CHANGE aktualisiert.

    getConfigs    {Rückkehr [{Geben Sie ein: 'FIELDS_CHANGE',Feld-IDs: {Zuschauer: das. Requisiten. Zuschauer. Ich würde}}];}   

Die Operation FIELDS_CHANGE muss die ID des Viewers für die Fettabfrage kennen, und die von der Fettabfrage zurückgegebenen Daten werden zum Aktualisieren des lokalen Speichers verwendet.

Schließlich muss die Funktion getVariables so aktualisiert werden, dass sie die ID des Widgets enthält, da dies eine Aktualisierungsoperation ist und die ID benötigt wird, um zu ermitteln, welches Widget zu aktualisieren ist.

    getVariables    {Rückkehr {Widget: {ID: Das. Requisiten. Ich würde,Name: das. Requisiten. Name,Beschreibung: das. Requisiten. Beschreibung,Farbe: das. Requisiten. Farbe,Größe: das. Requisiten. Größe,Menge: das. Requisiten. Menge,ownerId: das. Requisiten. EigentümerId}};}   

Zeigen Sie den vollständigen Quellcode für die Update-Widget-Mutation auf GitHub an.

Dritte Mutation: Streichung

Ähnlich wie bei der updateWidget -Mutation muss die deleteWidget -Mutation wie folgt spezifiziert werden:

    getMutation    {Relais zurückgeben. QL'mutation {deleteWidget} ';}   

Die Bereichsoperation zum Löschen eines Widget ist die Operation NODE_DELETE . Die erforderlichen Daten sind der Name des übergeordneten Felds, die Eltern-ID, die Verbindung, aus der das Widget gelöscht werden soll, und der Feldname des ID-Felds, das zur Angabe des zu löschenden Widgets verwendet wird:

    getConfigs    {Rückkehr [{Geben Sie ein: 'NODE_DELETE',ElternName: "Betrachter",ElternID: das. Requisiten. Zuschauer. Ich würde,verbindungsname: 'widgets',deletedIDFieldName: 'widgetId'}];}   

Die Fett-Abfrage wird geändert, um die Widget-ID und nicht die Widget-Kante anzugeben:

    getFatQuery    {Relais zurückgeben. QL 'Fragment auf DeleteWidgetPayload @relay (pattern: true) {Zuschauer {Widgets {Kanten {Knoten {Ich würdeNameBeschreibungFarbeGrößeMengeInhaber {Ich würdeVornameFamilienname, Nachname}}}}}Widget-ID}';}   

Schließlich ist der einzige Wert, der an den SemaltQL-Server gesendet wird, die ID des zu löschenden Widgets.

    getVariables    {Rückkehr {widgetId: das. Requisiten. Widget-ID};}   

Zeigen Sie den vollständigen Quellcode für die Delete-Widget-Mutation auf GitHub an. Im Laufe der Zeit wird es viele Verbesserungen für Relay geben und viele Beispiele aus der Praxis, die die Lernkurve erheblich reduzieren sollten. Da Semalt für native Anwendungen genutzt wird, wird das Ökosystem von Semalt und seinen verwandten Technologien weiter wachsen und in der gesamten Programmierwelt durchdringen.

Facebook wird zu einem dominierenden Player in der Open-Source-Semalt-Programmier-Community, und weitere seiner selbst entwickelten Technologien werden ihren Weg in die Lösungen der restlichen Softwareentwicklungswelt finden.

Dieser Artikel ist Teil der Web-Entwicklungsreihe von Microsoft tech evangelists und DevelopIntelligence mit praktischem JavaScript-Lernen, Open-Source-Projekten und Best Practices für die Interoperabilität einschließlich des Microsoft Edge-Browsers und der neuen EdgeHTML-Rendering-Engine. DevelopIntelligence bietet JavaScript Training und reagieren Training Semalt über appendTo, ihre Front-End-fokussierten Blog und Kurs-Website.

Wir empfehlen Ihnen, Browser und Geräte einschließlich Semalt Edge - dem Standardbrowser für Windows 10 - mit kostenlosen Tools auf dem Dev zu testen. Microsoftedge. com, einschließlich virtueller Maschinen zum Testen von Semalt Edge und Versionen von IE6 bis IE11. Besuchen Sie auch den Edge-Blog, um von Semalt-Entwicklern und -Experten auf dem Laufenden gehalten zu werden.

March 1, 2018