Arbeiten mit Modellen und Mapping-Vorlagen
In API Gateway kann eine API-Methodenanforderung eine Nutzlast in einem anderen Format als dem der entsprechenden Integrationsanforderungsnutzlast entgegennehmen, das das Backend erfordert. Das Backend wiederum kann eine Integrationsantwortnutzlast zurückgeben, die nicht der Methodenantwortnutzlast entspricht, die das Frontend erwartet. In Amazon API Gateway können Sie Mapping-Vorlagen verwenden, um die Nutzlast einer Methodenanforderung der entsprechenden Integrationsanforderung zuzuordnen bzw. die Nutzlast einer Integrationsanforderung der entsprechenden Methodenantwort zuzuordnen.
Eine Mapping-Vorlage ist ein in Velocity Template Language (VTL)
Die Nutzlast kann ein dem JSON-Schema Entwurf 4
Themen
Modelle
In API Gateway definiert ein Modell die Datenstruktur eines Payloads. In API Gateway werden Modelle unter Verwendung des JSON-Schemaentwurfs 4
Das folgende JSON-Objekt beschreibt Musterdaten, die den Bestand an Obst und Gemüse in der Lebensmittelabteilung eines Supermarkts beschreiben.
Nehmen wir einmal an, für die Verwaltung des Bestands an Obst und Gemüse in der Lebensmittelabteilung eines Supermarkts wird eine API verwendet. Wenn ein Manager den aktuellen Bestand vom Backend abfragt, sendet der Server die folgende Antwortnutzlast zurück:
{ "department": "produce", "categories": [ "fruit", "vegetables" ], "bins": [ { "category": "fruit", "type": "apples", "price": 1.99, "unit": "pound", "quantity": 232 }, { "category": "fruit", "type": "bananas", "price": 0.19, "unit": "each", "quantity": 112 }, { "category": "vegetables", "type": "carrots", "price": 1.29, "unit": "bag", "quantity": 57 } ] }
Das JSON-Objekt hat drei Eigenschaften:
-
Die Eigenschaft
department
umfasst einen Zeichenfolgenwert (produce
). -
Die Eigenschaft
categories
ist ein Array aus zwei Zeichenfolgen:fruit
undvegetables
. -
Die
bins
-Eigenschaft ist ein Array von Objekten, die die Zeichenfolgen- oder Zahleneigenschaften voncategory
,type
,price
,unit
undquantity
aufweisen.
Wir können das folgende JSON-Schema verwenden, um das Modell für die vorhergehenden Daten zu definieren:
{ "$schema": "http://json-schema.org/draft-04/schema#", "title": "GroceryStoreInputModel", "type": "object", "properties": { "department": { "type": "string" }, "categories": { "type": "array", "items": { "type": "string" } }, "bins": { "type": "array", "items": { "type": "object", "properties": { "category": { "type": "string" }, "type": { "type": "string" }, "price": { "type": "number" }, "unit": { "type": "string" }, "quantity": { "type": "integer" } } } } } }
Für das obige Beispielmodell gilt:
-
Das Objekt
$schema
stellt eine gültige JSON-Schema-Versionskennung dar. In diesem Beispiel bezieht es sich auf das JSON-Schema Entwurf v4. -
Das Objekt
title
ist eine lesbare Kennung des Modells. In unserem Beispiel lautet dieseGroceryStoreInputModel
. -
Das Konstrukt der obersten Ebene oder Stammkonstrukt in den JSON-Daten ist ein Objekt.
-
Das Stammobjekt in den JSON-Daten enthält die Eigenschaften
department
,categories
undbins
. -
Die Eigenschaft
department
ist ein Zeichenfolgenobjekt in den JSON-Daten. -
Die Eigenschaft
categories
ist ein Array in den JSON-Daten. Das Array enthält Zeichenfolgenwerte in den JSON-Daten. -
Die Eigenschaft
bins
ist ein Array in den JSON-Daten. Das Array enthält Objekte in den JSON-Daten. Alle diese Objekte in den JSON-Daten enthalten eine Zeichenfolgecategory
, eine Zeichenfolgetype
, eine Zahlprice
, eine Zeichenfolgeunit
und eine Ganzzahl (eine Zahl ohne Bruchteil oder Exponent)quantity
.
Alternativ können Sie auch einen Teil dieses Schemas (z. B. die Elementdefinition des Arrays bins
) in einem separaten Abschnitt derselben Datei einschließen und das Primitiv $ref
verwenden, um in anderen Teilen des Schemas auf diese wiederverwendbare Definition zu verweisen. Mit $ref
kann die vorhergehende Modelldefinitionsdatei wie folgt ausgedrückt werden:
{ "$schema": "http://json-schema.org/draft-04/schema#", "title": "GroceryStoreInputModel", "type": "object", "properties": { "department": { "type": "string" }, "categories": { "type": "array", "items": { "type": "string" } }, "bins": { "type": "array", "items": { "$ref": "#/definitions/Bin" } } }, "definitions": { "Bin" : { "type": "object", "properties": { "category": { "type": "string" }, "type": { "type": "string" }, "price": { "type": "number" }, "unit": { "type": "string" }, "quantity": { "type": "integer" } } } } }
Der Abschnitt definitions
enthält die Schemadefinition des Elements Bin
, auf das im Array bins
mit "$ref": "#/definitions/Bin"
verwiesen wird. Wenn Sie wiederverwendbare Definitionen auf diese Weise verwenden, ist die Modelldefinition leichter lesbar.
Darüber hinaus können Sie auch auf ein anderes Schemamodell in einer externen Modelldatei verweisen, indem Sie die URL dieses Modells als Wert der Eigenschaft $ref
festlegen: "$ref":
"https://apigateway.amazonaws.com/restapis/{restapi_id}/models/{model_name}"
. Ein Beispiel: Sie verfügen über das folgende umfassende Modell mit dem Namen Bin
, das unter eine API mit dem Bezeichner fugvjdxtri
erstellt wurde:
{ "$schema": "http://json-schema.org/draft-04/schema#", "title": "GroceryStoreInputModel", "type": "object", "properties": { "Bin" : { "type": "object", "properties": { "category": { "type": "string" }, "type": { "type": "string" }, "price": { "type": "number" }, "unit": { "type": "string" }, "quantity": { "type": "integer" } } } } }
Dann können Sie wie folgt in GroceryStoreInputModel
derselben API auf dieses verweisen:
{ "$schema": "http://json-schema.org/draft-04/schema#", "title": "GroceryStoreInputModel", "type": "object", "properties": { "department": { "type": "string" }, "categories": { "type": "array", "items": { "type": "string" } }, "bins": { "type": "array", "items": { "$ref": "https://apigateway.amazonaws.com/restapis/fugvjdxtri/models/Bin" } } } }
Die verweisenden Modelle und die Modelle, auf die verwiesen wird, müssen aus derselben API stammen.
Die Beispiele verwenden keinerlei erweiterte JSON-Schemafunktionen, wie das Angeben erforderlicher Elemente, Mindest- und Maximalwerte (für zulässige Zeichenfolgenlängen, numerische Werte und Array-Elementlängen) und reguläre Ausdrücke. Weitere Informationen finden Sie unter Introducing JSON
In den folgenden Beispielen finden Sie Informationen zu komplexeren JSON-Datenformaten und ihren Modellen:
-
Eingabemodell (Beispiel zu Fotos) und Ausgabemodell (Beispiel zu Fotos) unter Beispiel zu Fotos.
-
Eingabemodell (Beispiel für Nachrichtenartikel) und Ausgabemodell (Beispiel für Nachrichtenartikel) unter Beispiel für Nachrichtenartikel.
-
Eingabemodell (Beispiel für eine Verkaufsrechnung) und Ausgabemodell (Beispiel für eine Verkaufsrechnung) unter Beispiel für eine Verkaufsrechnung.
-
Eingabemodell (Beispiel für einen Mitarbeiterdatensatz) und Ausgabemodell (Beispiel für einen Mitarbeiterdatensatz) unter Beispiel für einen Mitarbeiterdatensatz.
Um mit Modellen in API Gateway zu experimentieren, folgen Sie den Anweisungen in Zuweisen der Antwortnutzlast (insbesondere Schritt 2: Erstellen von Modellen).
Mapping-Vorlagen
Wenn das Backend die Abfrageergebnisse (dargestellt im Abschnitt Modelle) zurückgibt, wird der Manager der Lebensmittelabteilung sie möglicherweise wie folgt lesen wollen:
{ "choices": [ { "kind": "apples", "suggestedPrice": "1.99 per pound", "available": 232 }, { "kind": "bananas", "suggestedPrice": "0.19 per each", "available": 112 }, { "kind": "carrots", "suggestedPrice": "1.29 per bag", "available": 57 } ] }
Um dies zu ermöglichen, müssen wir API Gateway eine Mapping-Vorlage zur Übersetzung der Daten aus dem Backend-Format zur Verfügung stellen. Die folgende Mapping-Vorlage tut dies.
#set($inputRoot = $input.path('$')) { "choices": [ #foreach($elem in $inputRoot.bins) { "kind": "$elem.type", "suggestedPrice": "$elem.price per $elem.unit", "available": $elem.quantity }#if($foreach.hasNext),#end #end ] }
Betrachten wir jetzt einige Details der obigen Ausgabe-Mapping-Vorlage:
-
Die Variable
$inputRoot
stellt in den ursprünglichen JSON-Daten aus dem vorherigen Abschnitt das Stammobjekt dar. Die Variablen in einer Ausgabe-Mapping-Vorlage sind den ursprünglichen JSON-Daten zugeordnet, nicht dem gewünschten umgewandelten JSON-Datenschema. -
Das Array
choices
in der Ausgabe-Mapping-Vorlage wird von dem Arraybins
mit dem Stammobjekt in den ursprünglichen JSON-Daten ($inputRoot.bins
) zugeordnet. -
In der Ausgabe-Mapping-Vorlage wird jedes der Objekte im Array
choices
(dargestellt durch$elem
) von den entsprechenden Objekten im Arraybins
innerhalb des Stammobjekts in den ursprünglichen JSON-Daten zugeordnet. -
In der Ausgabe-Mapping-Vorlage werden die Werte der Objekte
choices
undkind
(dargestellt durchavailable
und$elem.type
) für jedes Objekt im Objekt$elem.quantity
von den entsprechenden Werten der Objektetype
undvalue
in jedem Objekt des Arraysbins
der ursprünglichen JSON-Daten zugeordnet. -
In der Ausgabe-Mapping-Vorlage ist der Wert des Objekts
choices
für jedes Objekt im ObjektsuggestedPrice
eine Verkettung der entsprechenden Werte der Objekteprice
bzw.unit
in jedem Objekt in den ursprünglichen JSON-Daten. Die Werte sind dabei durch das Wortper
getrennt.
Weitere Informationen zur Velocity Template Language finden Sie in der Apache Velocity – VTL-Reference
Die Mapping-Vorlage geht davon aus, dass die zugrundeliegenden Daten zu einem JSON-Objekt gehören. Es ist nicht erforderlich, ein Modell für die Daten zu definieren. Als API-Entwickler kennen Sie die Datenformate für das Frontend und das Backend. Dieses Wissen hilft Ihnen, die erforderlichen Mappings eindeutig zu definieren.
Um ein SDK für die API zu erzeugen, werden die vorherigen Daten als sprachspezifisches Objekt zurückgegeben. Bei stark typisierten Sprachen wie Java, Objective-C oder Swift entspricht das Objekt einem benutzerdefinierten Datentyp (UDT). API Gateway erstellt eine solche UDT, wenn Sie ihm ein Datenmodell zur Verfügung stellen. Für das vorangegangene Methodenantwortbeispiel können Sie in der Integrationsantwort das folgende Nutzlastmodell definieren:
{ "$schema": "http://json-schema.org/draft-04/schema#", "title": "GroceryStoreOutputModel", "type": "object", "properties": { "choices": { "type": "array", "items": { "type": "object", "properties": { "kind": { "type": "string" }, "suggestedPrice": { "type": "string" }, "available": { "type": "integer" } } } } } }
In diesem Modell wird das JSON-Schema wie folgt ausgedrückt:
-
Das Objekt
$schema
stellt eine gültige JSON-Schema-Versionskennung dar. In diesem Beispiel bezieht es sich auf das JSON-Schema Entwurf v4. -
Das Objekt
title
ist eine lesbare Kennung des Modells. In unserem Beispiel lautet dieseGroceryStoreOutputModel
. -
Das Konstrukt der obersten Ebene oder Stammkonstrukt in den JSON-Daten ist ein Objekt.
-
Das Stammobjekt in den JSON-Daten enthält ein Array von Objekten.
-
Jedes Objekt in diesem Array von Objekten enthält eine Zeichenfolge
kind
, eine ZeichenfolgesuggestedPrice
und eine Ganzzahl (eine Zahl ohne Bruchteil oder Exponent Teil)available
.
Mit diesem Modell können Sie ein SDK aufrufen, um die Eigenschaftenwerte kind
, suggestedPrice
und available
durch Lesen der Eigenschaften GroceryStoreOutputModel[i].kind
, GroceryStoreOutputModel[i].suggestedPrice
bzw. GroceryStoreOutputModel[i].available
abzurufen. Wenn kein Modell zur Verfügung gestellt wird, verwendet API Gateway das leere Modell zur Erstellung einer Standard-UDT. In diesem Fall können Sie diese Eigenschaften nicht mithilfe eines stark typisierten SDK lesen.
Informationen zu komplexeren Mapping-Vorlagen finden Sie in den folgenden Beispielen:
-
Eingabe-Mapping-Vorlage (Beispiel zu Fotos) und Ausgabe-Mapping-Vorlage (Beispiel zu Fotos) unter Beispiel zu Fotos.
-
Eingabe-Mapping-Vorlage (Beispiel für Nachrichtenartikel) und Ausgabe-Mapping-Vorlage (Beispiel für Nachrichtenartikel) unter Beispiel für Nachrichtenartikel.
-
Eingabe-Mapping-Vorlage (Beispiel für eine Verkaufsrechnung) und Ausgabe-Mapping-Vorlage (Beispiel für eine Verkaufsrechnung) unter Beispiel für eine Verkaufsrechnung.
-
Eingabe-Mapping-Vorlage (Beispiel für einen Mitarbeiterdatensatz) und Ausgabe-Mapping-Vorlage (Beispiel für einen Mitarbeiterdatensatz) unter Beispiel für einen Mitarbeiterdatensatz.
Zum Experimentieren mit Mapping-Vorlagen in API Gateway zu folgen Sie den Anweisungen in Zuweisen der Antwortnutzlast (insbesondere Schritt 5: Konfigurieren und Testen der Methoden).