Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.
Schnittstellen und Unions in GraphQL
Das GraphQL-Typsystem unterstütztSchnittstellen
Das System vom Typ GraphQL unterstützt auchGewerkschaften
Der folgende Abschnitt ist eine Referenz für die Schematypisierung.
Beispiele für Benutzeroberflächen
Wir könnten eine repräsentierenEvent
Schnittstelle, die jede Art von Aktivität oder Zusammenkunft von Menschen darstellt. Einige mögliche Ereignistypen sindConcert
,Conference
, undFestival
. All diese Typen haben gemeinsame Merkmale: Name, Veranstaltungsort sowie Start- und Enddatum. Diese Typen haben auch Unterschiede; aConference
bietet eine Liste von Referenten und Workshops, während einConcert
verfügt über eine Band, die auftritt.
In der Schema Definition Language (SDL)Event
Die Schnittstelle ist wie folgt definiert:
interface Event { id: ID! name : String! startsAt: String endsAt: String venue: Venue minAgeRestriction: Int }
Und jeder der Typen implementiert dasEvent
Schnittstelle wie folgt:
type Concert implements Event { id: ID! name: String! startsAt: String endsAt: String venue: Venue minAgeRestriction: Int performingBand: String } type Festival implements Event { id: ID! name: String! startsAt: String endsAt: String venue: Venue minAgeRestriction: Int performers: [String] } type Conference implements Event { id: ID! name: String! startsAt: String endsAt: String venue: Venue minAgeRestriction: Int speakers: [String] workshops: [String] }
Schnittstellen sind nützlich zur Darstellung von Elementen, die in Form unterschiedlicher Typen auftreten können. Zum Beispiel könnten wir nach allen Ereignissen an einem bestimmten Veranstaltungsort suchen. Fügen wir nun folgendermaßen ein findEventsByVenue
-Feld zum Schema hinzu:
schema { query: Query } type Query { # Retrieve Events at a specific Venue findEventsAtVenue(venueId: ID!): [Event] } type Venue { id: ID! name: String address: String maxOccupancy: Int } type Concert implements Event { id: ID! name: String! startsAt: String endsAt: String venue: Venue minAgeRestriction: Int performingBand: String } interface Event { id: ID! name: String! startsAt: String endsAt: String venue: Venue minAgeRestriction: Int } type Festival implements Event { id: ID! name: String! startsAt: String endsAt: String venue: Venue minAgeRestriction: Int performers: [String] } type Conference implements Event { id: ID! name: String! startsAt: String endsAt: String venue: Venue minAgeRestriction: Int speakers: [String] workshops: [String] }
DasfindEventsByVenue
gibt eine Liste vonEvent
. Da GraphQL-Schnittstellenfelder von allen Implementierungstypen verwendet werden, können Sie jedes beliebige Feld der Event
-Schnittstelle auswählen (id
, name
, startsAt
, endsAt
, venue
und minAgeRestriction
). Alternativ können Sie mit GraphQL-Fragmenten
Schauen wir uns ein Beispiel für eine GraphQL-Abfrage an, die die Schnittstelle verwendet.
query { findEventsAtVenue(venueId: "Madison Square Garden") { id name minAgeRestriction startsAt ... on Festival { performers } ... on Concert { performingBand } ... on Conference { speakers workshops } } }
Die vorherige Abfrage gibt eine einzige Ergebnisliste aus und der Server kann die Ereignisse standardmäßig nach Startdatum sortieren.
{ "data": { "findEventsAtVenue": [ { "id": "Festival-2", "name": "Festival 2", "minAgeRestriction": 21, "startsAt": "2018-10-05T14:48:00.000Z", "performers": [ "The Singers", "The Screamers" ] }, { "id": "Concert-3", "name": "Concert 3", "minAgeRestriction": 18, "startsAt": "2018-10-07T14:48:00.000Z", "performingBand": "The Jumpers" }, { "id": "Conference-4", "name": "Conference 4", "minAgeRestriction": null, "startsAt": "2018-10-09T14:48:00.000Z", "speakers": [ "The Storytellers" ], "workshops": [ "Writing", "Reading" ] } ] } }
Da Ergebnisse als eine einzelne Sammlung von Ereignissen zurückgegeben werden, ist die Verwendung von Schnittstellen zur Darstellung gemeinsamer Merkmale für die Sortierung der Ergebnisse sehr hilfreich.
Beispiele für Vereinigungen
Wie bereits erwähnt, definieren Gewerkschaften keine gemeinsamen Gruppen von Feldern. Ein Suchergebnis kann viele verschiedene Typen repräsentieren. Mit dem Event
-Schema können Sie eine SearchResult
-Vereinigung definieren. Gehen Sie wie folgt vor:
type Query { # Retrieve Events at a specific Venue findEventsAtVenue(venueId: ID!): [Event] # Search across all content search(query: String!): [SearchResult] } union SearchResult = Conference | Festival | Concert | Venue
In diesem Fall, um ein beliebiges Feld auf unserem abzufragenSearchResult
Union, Sie müssen Fragmente verwenden:
query { search(query: "Madison") { ... on Venue { id name address } ... on Festival { id name performers } ... on Concert { id name performingBand } ... on Conference { speakers workshops } } }
Geben Sie Auflösung einAWS AppSync
Die Typenauflösung ist der Mechanismus, durch den die GraphQL-Engine einen aufgelösten Wert als bestimmten Objekttyp identifiziert.
Um zum Beispiel für die Union-Suche zurückzukehren: Vorausgesetzt, dass unsere Abfrage zu Ergebnissen geführt hat, muss jedes Element in der Ergebnisliste als einer der möglichen Typen dargestellt werdenSearchResult
Union definiert (das heißt,Conference
,Festival
,Concert
, oderVenue
).
Da die Logik zum Unterscheiden zwischen Festival
, Venue
und Conference
von den Anwendungsanforderungen abhängt, muss die GraphQL-Engine Informationen erhalten, um unsere möglichen Typen in den Raw-Ergebnissen zu identifizieren.
MitAWS AppSync, dieser Hinweis wird durch ein Metafeld mit dem Namen dargestellt__typename
, dessen Wert dem Namen des identifizierten Objekttyps entspricht.__typename
ist für Rückgabetypen erforderlich, bei denen es sich um Interfaces oder Unions handelt.
Beispiel für die Typauflösung
Verwenden wir erneut das vorherige Schema. Sie können dies reproduzieren, indem Sie zur Konsole gehen und Folgendes unter der Seite Schema hinzufügen:
schema { query: Query } type Query { # Retrieve Events at a specific Venue findEventsAtVenue(venueId: ID!): [Event] # Search across all content search(query: String!): [SearchResult] } union SearchResult = Conference | Festival | Concert | Venue type Venue { id: ID! name: String! address: String maxOccupancy: Int } interface Event { id: ID! name: String! startsAt: String endsAt: String venue: Venue minAgeRestriction: Int } type Festival implements Event { id: ID! name: String! startsAt: String endsAt: String venue: Venue minAgeRestriction: Int performers: [String] } type Conference implements Event { id: ID! name: String! startsAt: String endsAt: String venue: Venue minAgeRestriction: Int speakers: [String] workshops: [String] } type Concert implements Event { id: ID! name: String! startsAt: String endsAt: String venue: Venue minAgeRestriction: Int performingBand: String }
Hängen wir nun einen Resolver an das Query.search
-Feld an. In derResolvers
Abschnitt, wählenAnhängen, erstelle ein neuesDatenquellevom TypKEINE, und dann nenne esStubDataSource. Für dieses Beispiel nehmen wir an, wir haben die Ergebnisse aus einer externen Quelle abgerufen und codieren die abgerufenen Ergebnisse fest in unserer Zuweisungsvorlage für Anforderungen.
Geben Sie im Bereich der Anforderungszuweisungsvorlage Folgendes ein:
{ "version" : "2018-05-29", "payload": ## We are effectively mocking our search results for this example [ { "id": "Venue-1", "name": "Venue 1", "address": "2121 7th Ave, Seattle, WA 98121", "maxOccupancy": 1000 }, { "id": "Festival-2", "name": "Festival 2", "performers": ["The Singers", "The Screamers"] }, { "id": "Concert-3", "name": "Concert 3", "performingBand": "The Jumpers" }, { "id": "Conference-4", "name": "Conference 4", "speakers": ["The Storytellers"], "workshops": ["Writing", "Reading"] } ] }
Wenn die Anwendung den Typnamen als Teil der zurückgibtid
Feld, die Typauflösungslogik muss das analysierenid
Feld, um den Typnamen zu extrahieren und dann das hinzuzufügen__typename
Feld zu jedem der Ergebnisse. Sie können die Logik in der Antwortzuweisungsvorlage folgendermaßen umsetzen:
Anmerkung
Sie können diese Aufgabe auch als Teil Ihrer Lambda-Funktion ausführen, wenn Sie die Lambda-Datenquelle verwenden.
#foreach ($result in $context.result) ## Extract type name from the id field. #set( $typeName = $result.id.split("-")[0] ) #set( $ignore = $result.put("__typename", $typeName)) #end $util.toJson($context.result)
Führen Sie die folgende Abfrage aus:
query { search(query: "Madison") { ... on Venue { id name address } ... on Festival { id name performers } ... on Concert { id name performingBand } ... on Conference { speakers workshops } } }
Die Abfrage liefert die folgenden Ergebnisse:
{ "data": { "search": [ { "id": "Venue-1", "name": "Venue 1", "address": "2121 7th Ave, Seattle, WA 98121" }, { "id": "Festival-2", "name": "Festival 2", "performers": [ "The Singers", "The Screamers" ] }, { "id": "Concert-3", "name": "Concert 3", "performingBand": "The Jumpers" }, { "speakers": [ "The Storytellers" ], "workshops": [ "Writing", "Reading" ] } ] } }
Die Typenauflösungslogik variiert je nach Anwendung. Sie können beispielsweise eine andere Identifizierungslogik verwenden, die prüft, ob bestimmte Felder oder auch Kombinationen von Feldern vorhanden sind. Sie können also feststellen, ob das performers
-Feld vorhanden ist, um ein Festival
zu identifizieren, oder die Kombination der Felder speakers
und workshops
, um eine Conference
zu identifizieren. Letztlich liegt es an Ihnen, die Logik zu definieren, die Sie verwenden möchten.