Sie sehen die Dokumentation zu Apigee Edge.
Gehen Sie zur
Apigee X-Dokumentation. Weitere Informationen
Bedingte Anweisungen sind eine einheitliche Steuerstruktur in allen Programmiersprachen. Wie eine Programmiersprache unterstützt die API-Proxykonfiguration bedingte Anweisungen für Abläufe, Richtlinien, Schritte und RouteRules. Wenn Sie bedingte Anweisungen definieren, definieren Sie das dynamische Verhalten für Ihre API. Mit diesem dynamischen Verhalten können Sie XML beispielsweise nur für Mobilgeräte in JSON umwandeln oder an eine Backend-URL weiterleiten, die auf dem Inhaltstyp oder dem HTTP-Verb der Anfragenachricht basiert.
In diesem Thema erfahren Sie, wie Sie Bedingungen verwenden, um API-Verwaltungsfeatures dynamisch zur Laufzeit anzuwenden, ohne Code schreiben zu müssen.
Bedingte Anweisungen konfigurieren
Bedingtes Verhalten wird in API-Proxys mithilfe einer Kombination aus Bedingungen und Variablen implementiert. Eine bedingte Anweisung wird mit einem Bedingungselement erstellt. Die folgende Bedingung ist leer:
<Condition></Condition>
Zum Erstellen einer bedingten Anweisung fügen Sie einen Bedingungsoperator und eine Variable hinzu, um die folgende Struktur zu erstellen:
<Condition>{variable.name}{operator}{"value"}</Condition>
Unterstützte bedingte Operatoren sind =
(gleich), !=
(ungleich) und >
(größer als). Zur besseren Lesbarkeit können Sie auch die Bedingungen als Text schreiben: equals
, notequals
, greaterthan
.
Wenn Sie mit URI-Pfaden arbeiten, können Sie ~/
oder MatchesPath
verwenden. Außerdem können Sie mit dem Operator ~~ auch reguläre JavaRegex-Ausdrücke abgleichen.
Bedingungen werden verwendet, um bedingte API-Proxy-Abläufe für Backend-API-Ressourcen zu definieren, wie unter Erstellen von bedingten Abläufen für Backend-API-Ressourcen erstellen beschrieben. Eine vollständige Liste der Bedingungen finden Sie in der Referenz zu Bedingungen.
Variablen
Dazu werden die Werte von Variablen ausgewertet. Eine Variable ist das Attribut einer HTTP-Transaktion, die von einem API-Proxy ausgeführt wird, oder das Attribut einer API-Proxy-Konfiguration selbst. Immer, wenn ein API-Proxy eine Anfrage von einer App erhält, füllt Apigee Edge ein Liste mit Variablen, die sich auf Dinge wie die Systemzeit, das Netzwerk der App Informationen, HTTP-Header in Nachrichten, die API-Proxy-Konfiguration, Richtlinienausführungen usw. Dadurch wird ein umfassender Kontext erstellt, mit dem Sie bedingte Anweisungen einrichten können.
Für Variablen wird immer die Punktschreibweise verwendet. Beispielsweise sind HTTP-Header in der Anfragenachricht als Variablen mit dem Namen request.header.{header_name}
verfügbar. Für die Auswertung des Content-Type-Headers können Sie die Variable request.header.Content-type
verwenden. Beispiel: request.header.Content-type = "application/json"
gibt an, dass der Inhaltstyp der Anfrage JSON sein soll.
Angenommen, Sie müssen eine bedingte Anweisung erstellen, die bewirkt, dass eine Richtlinie nur dann erzwungen wird, wenn eine Anfragenachricht eine GET-Anfrage ist. Um eine Bedingung zu erstellen, mit der das HTTP-Verb einer Anfrage ausgewertet wird, erstellen Sie unten die bedingte Anweisung. Die Variable in dieser Bedingung ist request.verb
. Der Wert der Variablen ist GET
. Der Operator ist =
.
<Condition>request.verb = "GET"</Condition>Sie können auch Folgendes verwenden:
<Condition>request.verb equals "GET"</Condition>
Edge verwendet eine solche Anweisung, um Bedingungen zu bewerten. Im obigen Beispiel wird der Wert „true“ zurückgegeben, wenn das mit der Anfrage verknüpfte HTTP-Verb GET ist. Wenn das der Anfrage zugeordnete HTTP-Verb POST lautet, wird die Anweisung als „false“ ausgewertet.
Für ein dynamisches Verhalten können Sie Bedingungen mit Abläufen, Schritten und Routingregeln verknüpfen.
Wenn Sie eine Bedingung an einen Ablauf anhängen, erstellen Sie einen „bedingten Ablauf”. Bedingte Flows werden nur ausgeführt, wenn die Bedingung als wahr ausgewertet wird. Sie können beliebig viele Richtlinien an einen bedingten Ablauf anhängen. Mit bedingten Abläufen können Sie hochgradig spezialisierte Verarbeitungsregeln für Anfrage- oder Antwortnachrichten erstellen, die bestimmte Kriterien erfüllen.
So erstellen Sie beispielsweise einen Ablauf, der nur ausgeführt wird, wenn das Anfrageverb ein GET-Vorgang ist:
<Flows> <Flow name="ExecuteForGETs"> <Condition>request.verb="GET"</Condition> </Flow> </Flows>
So erstellen Sie einen Ablauf für GET- und einen weiteren für POST-Anfragen:
<Flows> <Flow name="ExecuteForGETs"> <Condition>request.verb="GET"</Condition> </Flow> <Flow name="ExecuteForPOSTs"> <Condition>request.verb="POST"</Condition> </Flow> </Flows>
Wie im folgenden Beispiel gezeigt, können Sie die Bedingung auf den Richtlinienschritt selbst anwenden. Die folgende Bedingung bewirkt, dass die VerifyApiKey-Richtlinie nur erzwungen wird, wenn eine Anfragenachricht eine POST-Anfrage ist.
<PreFlow name="PreFlow"> <Request> <Step> <Condition>request.verb equals "POST"</Condition> <Name>VerifyApiKey</Name> </Step> </Request> </PreFlow>
Nachdem Sie diese bedingten Abläufe definiert haben, können Sie sie mit Richtlinien verknüpfen. Dadurch kann ein API-Proxy eine Reihe von Richtlinien für GET-Anfragen und eine weitere Reihe von Richtlinien für POST-Anfragen erzwingen.
Umfassende Referenzinformationen finden Sie in den folgenden Ressourcen:
Beispiel 1
Das folgende Beispiel zeigt einen einzelnen bedingten Namen mit dem Namen Convert-for-devices
, der im ProxyEndpoint-Antwortfluss konfiguriert wurde. Fügen Sie die Bedingung als Element zu der Entität hinzu, für die die Bedingung gilt. In diesem Beispiel ist die Bedingung eine Komponente des Ablaufs.
Daher wird der Ablauf ausgeführt, wenn die Anweisung mit „true” ausgewertet wird.
<Flows> <Flow name="Convert-for-devices"> <Condition>(request.header.User-Agent = "Mozilla")</Condition> <Response> <Step><Name>ConvertToJSON</Name></Step> </Response> </Flow> </Flows>
Für jede von einer Anwendung empfangene Anfrage speichert Edge die Werte aller HTTP-Header, die als Variablen vorhanden sind. Wenn die Anfrage einen HTTP-Header mit dem Namen User-Agent
enthält, werden dieser Header und sein Wert als Variable mit dem Namen request.header.User-Agent
gespeichert.
Bei der obigen ProxyEndpoint-Konfiguration überprüft Edge den Wert des
request.header.User-Agent
, um zu sehen, ob die Bedingung als
true fest.
Wenn die Bedingung als „true“ ausgewertet wird, d. h. der Wert der Variable request.header.User-Agent
gleich Mozilla
ist, wird der bedingte Ablauf ausgeführt und die XML-zu-JSON-Richtlinie namens ConvertToJSON
wird erzwungen. Andernfalls wird der Ablauf nicht ausgeführt und die XML-Antwort wird unverändert (im XML-Format) an die anfragende Anwendung zurückgegeben.
Beispiel 2
Nehmen wir ein konkretes Beispiel, in dem Sie die Antwortnachricht von XML in JSON umwandeln müssen, aber nur auf Mobilgeräten. Erstellen Sie zuerst die Richtlinie, die die XML-formatierte Antwort von der Weather API in JSON konvertiert:
<XMLToJSON name="ConvertToJSON"> <Options> </Options> <OutputVariable>response</OutputVariable> <Source>response</Source> </XMLToJSON>
Die Richtlinienkonfiguration oben weist den API-Proxy an, die Antwortnachricht aufzunehmen, eine Konvertierung von XML in JSON mit den Standardeinstellungen durchzuführen und das Ergebnis in die neue Antwortnachricht zu schreiben. Wenn Sie eine Anfrage-Nachricht von XML in JSON konvertieren, legen Sie einfach beide Werte auf request
fest.
Da Sie Antworten von XML in JSON konvertieren möchten, müssen Sie einen bedingten Antwortfluss für die Konvertierung konfigurieren. Wenn Sie beispielsweise alle Antworten von XML in JSON konvertieren möchten, bevor sie an die Client-App zurückgegeben werden, konfigurieren Sie den folgenden ProxyEndpoint-Antwortablauf.
<Flows> <Flow name="Convert-for-devices"> <Response> <Step><Name>ConvertToJSON</Name></Step> </Response> </Flow> </Flows>
Wenn Sie die API mit der Standardanfrage aufrufen, wird die Antwort in JSON formatiert.
Ihr Ziel ist jedoch, Wetterberichte nur in JSON umzuwandeln, wenn der anfordernde Client ein Mobilgerät ist. Um dieses dynamische Verhalten zu aktivieren, müssen Sie dem Ablauf eine bedingte Anweisung hinzufügen.
Bedingten Ablauf testen
In dieser Beispielanfrage ist der HTTP-Header User-Agent
auf Mozilla
gesetzt. Dadurch wird die bedingte Anweisung als „true“ ausgewertet und der bedingte Ablauf Convert-for-devices
wird ausgeführt.
$ curl -H "User-Agent:Mozilla" http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282
Oder für eine optimierte Darstellung, wo Python verfügbar ist:
$ curl -H "User-Agent:Mozilla" http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282 | python -mjson.tool
Beispielantwort:
. . . "yweather_forecast": [ { "code": "11", "date": "12 Dec 2012", "day": "Wed", "high": "55", "low": "36", "text": "Showers" }, { "code": "32", "date": "13 Dec 2012", "day": "Thu", "high": "56", "low": "38", "text": "Sunny" } ] } . . .
Eine Anfrage ohne den Header User-Agent
oder mit einem anderen Wert als Mozilla
führt zu einer Antwort im XML-Format.
$ curl http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282
Die unveränderte XML-Antwort wird zurückgegeben.
Beispielantwort:
<yweather:forecast day="Wed" date="12 Dec 2012" low="36" high="55" text="Showers" code="11" /> <yweather:forecast day="Thu" date="13 Dec 2012" low="38" high="56" text="Sunny" code="32" />
Musterabgleich
In diesem Abschnitt wird beschrieben, wie Sie in einem Apigee-Ablauf einen Musterabgleich mit Bedingungen verwenden.
Operatoren
In diesem Abschnitt wird beschrieben, wie die folgenden Musterabgleichsoperatoren in bedingten Anweisungen verwendet werden:
- Matches-Operator: Einfacher Musterabgleich
- JavaRegex-Operator: Gezielterer Abgleich
- MatchesPath-Operator: Pfadfragmentabgleich
Stimmt überein mit
Sehen wir uns zuerst den Bedingungsoperator „Matches“ bzw. „~“ an. Diese beiden Operatoren sind identisch – die englische Version „Matches“ gilt als besser lesbar.
Zusammenfassung: Der Matches-Operator bietet zwei Möglichkeiten. Sie geben entweder den String wörtlich ein oder führen einen Platzhalterabgleich mit „*“ aus. Der Platzhalter entspricht dann erwartungsgemäß null oder mehr Zeichen. Und so funktioniert es:
Die folgende XML-Datei zeigt eine Schrittbedingung. Sie führt die SomePolicy-Richtlinie aus, wenn die Bedingung als true ausgewertet wird. In diesem Beispiel testen wir die Variable proxy.pathsuffix
,
integrierte Variable in Edge, die das Pfadsuffix der Anfrage speichert. Sie können jedoch den Wert einer beliebigen Ablaufvariable testen, die einen String enthält. Wenn der Basispfad der eingehenden Anfrage also /animals
und die Anfrage /animals/cat
ist, ist das Pfadsuffix der Literalstring „/cat
”.
<PreFlow name="PreFlow"> <Request> <Step> <Condition>(proxy.pathsuffix Matches "/cat")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
Frage: Welches Proxypfad-Suffix verursacht die Ausführung von SomePolicy? Es gibt nur eine Möglichkeit.
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/cat
Wird die Richtlinie ausgeführt? Ja, da das Suffix des Proxypfads exakt mit „/cat
” übereinstimmt. Sie wird nicht ausgeführt, wenn das Suffix /bat
, /dog
, „/
” oder ein anderes Element ist.
Betrachten wir nun diese bedingte Anweisung, in der das Platzhalterzeichen „*
“ verwendet wird:
<Condition>(proxy.pathsuffix Matches "/*at")</Condition>
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/cat
Wird die Richtlinie ausgeführt? Ja, da der Platzhalter mit einem beliebigen Zeichen übereinstimmt und „"/cat
” eine Übereinstimmung ist.
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/bat
Wird die Richtlinie ausgeführt? Ja, da der Platzhalter mit einem beliebigen Zeichen übereinstimmt, sodass "/bat"
eine Übereinstimmung ist.
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/owl
Wird die Richtlinie ausgeführt? Ganz bestimmt nicht – obwohl der Platzhalter mit "o
" übereinstimmt,
die Buchstaben „wl
“ nicht zugeordnet werden.
Verschieben Sie den Platzhalter jetzt an das Ende des Suffixes:
<Condition>(proxy.pathsuffix Matches "/cat*")</Condition>
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/cat
Wird die Richtlinie ausgeführt? Ja, da der Platzhalter null oder mehr Zeichen entspricht.
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/bat
Wird die Richtlinie ausgeführt? Nein, „/bat
“ ist keine Übereinstimmung.
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/cat123
Wird die Richtlinie ausgeführt? Ja, der Platzhalter entspricht null oder mehr Zeichen, sodass „123
“ eine Übereinstimmung ergibt.
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/cat/bird/mouse
Wird die Richtlinie ausgeführt? Ja, da der Platzhalter null oder mehr Zeichen entspricht, sodass „/bird/mouse
“ eine Übereinstimmung ergibt. Wie Sie sehen, kann ein Ausdruck wie dieser Probleme verursachen, da er alles nach den Literalzeichen abgleicht.
Frage: Berücksichtigt der Matches-Operator die Groß-/Kleinschreibung?
Ja. Angenommen, Sie haben eine Bedingung wie diese:
<Condition>(proxy.pathsuffix Matches "/*At")</Condition>
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/cat
Wird die Richtlinie ausgeführt? Nein, der Platzhalter entspricht jedem Buchstaben (unabhängig von der Groß-/Kleinschreibung), aber der Kleinbuchstabe „a“ nicht mit "A" übereinstimmt.
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/bAt
Wird die Richtlinie ausgeführt? Ja, die Groß-Kleinschreibung stimmt überein.
Frage: Wie maskiere ich Zeichen mit dem Matches-Operator?
Verwenden Sie das Zeichen „%“, um reservierte Zeichen zu maskieren. Beispiel:
<Condition>(proxy.pathsuffix Matches "/c%*at")</Condition>
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/cat
Wird die Richtlinie ausgeführt? Nein, der Operator "Matches" sucht nach dem Literalstring „kat*at“.
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/c*at
Frage: Wird die Richtlinie ausgeführt?
Ja, dieser Pfad ist zwar etwas ungewöhnlich, stimmt aber überein.
JavaRegex
Wie Sie sehen, eignet sich der Operator „Matches” auch gut für einfache Situationen. Sie können jedoch einen anderen Operator verwenden: den Operator „JavaRegex” oder „~~”. Diese beiden Operatoren sind identisch, aber JavaRegex wird als besser lesbar betrachtet. Sie heißt JavaRegex, weil sie reguläre Ausdrücke Musterabgleich, und Edge folgt denselben Regeln wie die Klassen in java.util.regex -Paket in der Sprache Java. Die Art und Weise, wie der JavaRegex-Operator funktioniert, unterscheidet sich stark vom Operator „Matches”. Daher ist es wichtig, die beiden Operatoren nicht zu verwechseln.
Zusammenfassung: Mit dem Operator „JavaRegex“ können Sie in bedingten Anweisungen die Syntax für reguläre Ausdrücke verwenden.
Der folgende Code zeigt eine Schrittbedingung: Sie führt die SomePolicy-Richtlinie aus, wenn die Bedingung
mit "true" ausgewertet wird. In diesem Beispiel testen wir die in Edge integrierte Variable proxy.pathsuffix
, in der das Pfadsuffix der Anfrage gespeichert wird. Wenn der Basispfad der eingehenden Anfrage /animals
und die Anfrage /animals/cat
ist, ist das Pfadsuffix der Literalstring „/cat
”.
<PreFlow name="PreFlow"> <Request> <Step> <Condition>(proxy.pathsuffix JavaRegex "/cat")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
Frage: Welches Proxypfad-Suffix verursacht die Ausführung von SomePolicy? Wie beim Matches-Operator gibt es auch hier nur eine Möglichkeit.
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/cat
Wird die Richtlinie ausgeführt? Ja, da das Suffix des Proxypfads exakt mit „/cat
” übereinstimmt. Sie wird nicht ausgeführt, wenn das Suffix /bat
oder /dog
oder anders lautet.
Nun erstellen wir einen regulären Ausdruck mit dem Qantifizierer „*“. Dieser Quantifizierer gleicht das voranstehende Zeichen keinmal oder mehrmals ab.
<Condition>(proxy.pathsuffix JavaRegex "/c*t")</Condition>
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/cat
Wird die Richtlinie ausgeführt? Nein! Der Quantifizierer „*“ entspricht null oder mehr der vorhergehenden Zeichen, also „c
“.
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/ccccct
Wird die Richtlinie ausgeführt? Ja, da der Platzhalter keinem oder mehreren der vorherigen Zeichen entspricht.
Als Nächstes verwenden wir den Quantifier „?
“, der das voranstehende Zeichen einmal oder keinmal abgleicht.
<Condition>(proxy.pathsuffix JavaRegex "/ca?t")</Condition>
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/cat
Wird die Richtlinie ausgeführt? Ja. Der Quantifizierer „?
“ entspricht null oder einem Vorkommen des vorhergehenden Zeichens, also „a
“.
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/ct
Wird die Richtlinie ausgeführt? Ja. „?
“ Quantifizierer entspricht einem oder
keines des vorangehenden Zeichens. In diesem Fall gibt es kein -Zeichen, sodass das
wird als wahr ausgewertet.
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/caat
Wird die Richtlinie ausgeführt? Nein. Der Quantifizierer „?“ entspricht einema
der vorherigen Zeichen, also einem „a
“.
Als Nächstes verwenden wir den regulären Ausdruck „[abc]
“ für „Gruppierungen“. Er entspricht dem Zeichen „a
“, „b
“ oder „c
“.
<Condition>(proxy.pathsuffix JavaRegex "/[cbr]at")</Condition>
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/cat
Wird die Richtlinie ausgeführt? Ja. Wir verwenden hier reguläre Ausdrücke und der Ausdruck „[cbr]
“ entspricht einem „c“, „b“ oder „r“. Diese Aufrufe sind auch Übereinstimmungen:
GET http://artomatic-test.apigee.net/matchtest/bat
GET http://artomatic-test.apigee.net/matchtest/rat
Dies ist jedoch keine Übereinstimmung:
GET http://artomatic-test.apigee.net/matchtest/mat
Frage: Berücksichtigt der JavaRegex-Operator die Groß-/Kleinschreibung?
Ja. Angenommen, Sie haben eine Bedingung wie diese:
<Condition>(proxy.pathsuffix JavaRegex "/ca?t")</Condition>
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/cat
Wird die Richtlinie ausgeführt? Ja, der Regex stimmt mit null oder einem der vorhergehenden Zeichen überein, also „a“.
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/cAt
Frage: Wird die Richtlinie ausgeführt?
Nein, weil das großgeschriebene „A“ nicht mit dem kleingeschriebenen „a“ übereinstimmt.
MatchesPath
Der Operator MatchesPath
kann auch so angegeben werden: „~/”. Sieht etwas wie die Operatoren Matches
(~) und JavaRegex (~~) aus. MatchesPath ist jedoch völlig anders.
Beachten Sie, dass dieser Operator einen Pfad als eine Zusammensetzung aus verschiedenen Teilen betrachtet. Wenn der Pfad also /animals/cats/wild
lautet, können Sie sich den Pfad als eine Zusammensetzung aus den Teilen „/animals
“, „/cats
“ und „/wild
“ vorstellen.
Mit dem Operator MatchesPath
können Sie zwei Platzhalterschreibweisen verwenden: ein einzelnes Sternchen (*) und ein doppeltes Sternchen (**). Das einzelne Sternchen entspricht einem Pfadelement. Das doppelte Sternchen entspricht einem oder mehreren Pfadelementen.
Sehen wir uns ein Beispiel an. In diesem Beispiel testen wir die Variable proxy.pathsuffix
,
eine integrierte Variable in Edge, die das Pfadsuffix der Anfrage speichert. Sie können jedoch den Wert einer beliebigen Ablaufvariable testen, die einen String enthält.
<PreFlow name="PreFlow"> <Request> <Step> <Condition>(proxy.pathsuffix MatchesPath "/animals/*")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
Frage: Welches Proxypfad-Suffix verursacht die Ausführung von SomePolicy?
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/animals
Frage: Wird die Richtlinie ausgeführt?
Nein, weil für die Bedingung ein weiteres Pfadelement nach „/animals
“ erforderlich ist, das durch „/*
“ angegeben wird.
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/animals
/
Wird die Richtlinie ausgeführt? Ja, der Pfad enthält ein weiteres Pfadelement (der Teil nach „/animals/
“), ist aber leer.
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/animals/cats
Wird die Richtlinie ausgeführt? Ja, weil der Pfad eindeutig ein Element („/cats
“) enthält
nach „/animals
“
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild
Frage: Wird die Richtlinie ausgeführt?
Nein, weil das einzelne Sternchen nur mit einem Pfadelement übereinstimmt und diese API mehrere Elemente nach „/animals
“ enthält.
Verwenden wir jetzt das doppelte Sternchen:
<PreFlow name="PreFlow"> <Request> <Step> <Condition>(proxy.pathsuffix MatchesPath "/animals/**")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
Frage: Welches Proxypfad-Suffix verursacht die Ausführung von SomePolicy?
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/animals
Wird die Richtlinie ausgeführt? Nein, weil für die Bedingung mindestens ein nachfolgendes Pfadelement erforderlich ist
angegeben durch "/**
".
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/animals
/
Wird die Richtlinie ausgeführt?
Ja, der Pfad enthält ein weiteres Pfadelement (der Teil nach „/animals/
“), ist aber leer.
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/animals/cats
Wird die Richtlinie ausgeführt?
Ja, weil der Pfad mindestens ein Element enthält, das nach „/animals
“ kommt.
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild
Wird die Richtlinie ausgeführt?
Ja, weil der Pfad mehr als ein Element hinter „/animals
“ enthält.
Sternchen kombinieren
Sie können Kombinationen aus einem einzelnen Sternchen (*) und doppelten Sternchen (**) verwenden, um den Pfadabgleich zu verfeinern.
<PreFlow name="PreFlow"> <Request> <Step> <Condition>(proxy.pathsuffix MatchesPath "/animals/*/wild/**")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
API-Aufruf:
Alle folgenden API-Aufrufe liefern eine Übereinstimmung:
GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild/
und
GET http://artomatic-test.apigee.net/matchtest/animals/dogs/wild/austrailian
und
GET
http://artomatic-test.apigee.net/matchtest/animals/birds/wild/american/finches
API-Ressourcen
RESTful-Dienste sind Sammlungen von API-Ressourcen. Eine API-Ressource ist ein URI-Pfadfragment, das eine Entität identifiziert, auf die Entwickler durch Aufrufen Ihrer API zugreifen können. Wenn Ihr Dienst beispielsweise Wetterberichte und Wettervorhersagen bereitstellt, kann Ihr Backend-Dienst zwei API-Ressourcen definieren:
- http://mygreatweatherforecast.com/reports
- http://mygreatweatherforecast.com/forecasts
Wenn Sie einen API-Proxy erstellen (wie unter Ersten API-Proxy erstellen gezeigt), müssen Sie zumindest eine Alias-Basis-URL erstellen, die Ihrem Backend-Dienst zugeordnet ist. Beispiele:
Backend-Basis-URL | Neue/entsprechende API-Proxy-URL |
---|---|
http://mygreatweatherforecast.com | http://{your_org}-{environment}.apigee.net/mygreatweatherforecast |
An dieser Stelle können Sie mit beiden URLs API-Aufrufe an Ihr Backend senden. Wenn Sie jedoch die API-Proxy-URL verwenden, wird es interessant.
Zusätzlich zu den API-Analysen, die Edge beim Verwenden des API-Proxys zu erfassen beginnt, können Proxys Sie können auch bedingte Datenflüsse definieren, die den Ressourcen in Ihrem Back-End zugeordnet sind. Im Wesentlichen: „Wenn ein GET-Aufruf an die /reports-Ressource eingeht, sollte Edge eine Aktion ausführen.“
In der folgenden Abbildung ist der Verhaltensunterschied zwischen zwei URLs zu sehen, die letztendlich auf dasselbe Backend zugreifen. Eine ist die Ressourcen-URL ohne Proxy, die andere ein Edge-API-Proxy mit einem bedingten Fluss zur selben Back-End-Ressource. Weitere Informationen zu bedingten Abläufen finden Sie weiter unten.
So werden API-Proxys zu bestimmten Backend-Ressourcen zugeordnet
Wenn eine API-Proxy-URL der Basis-URL des Backend-Dienstes (beim Erstellen des Proxys) zugeordnet ist, können Sie bedingte Abläufe bestimmten Ressourcen zuordnen, wie z. B. die bereits erwähnten Ressourcen /reports
und /forecasts
.
Angenommen, Sie möchten, dass Edge /reports
etwas unternimmt/forecasts
, wenn Aufrufe an die Ressource /reports
oder /forecasts
erfolgen. Zu diesem Zeitpunkt wird Edge noch nicht mitgeteilt,
und auf Aufrufe an diese Ressourcen warten sollte. Dazu verwenden Sie Bedingungen. In Ihrem Edge API-Proxy können Sie bedingte Datenflüsse für
/reports
und /forecasts
. Zu Konzeptzwecken veranschaulicht die folgende API-Proxy-XML, wie diese Bedingungen aussehen könnten.
<Flows> <Flow name="reports"> <Description/> <Request/> <Response/> <Condition>(proxy.pathsuffix MatchesPath "/reports") and (request.verb = "GET")</Condition> </Flow> <Flow name="forecasts"> <Description/> <Request/> <Response/> <Condition>(proxy.pathsuffix MatchesPath "/forecasts") and (request.verb = "GET")</Condition> </Flow> </Flows>
Diese Bedingungen geben vor: „Wenn eine GET-Anfrage mit /reports
und /forecasts
in der URL eingeht, führt Edge das aus, was Sie als API-Entwickler über die Richtlinien vorgeben, die Sie mit diesen Abläufen verknüpfen“.
Hier sehen Sie ein Beispiel dafür, wie Sie Edge mitteilen, was zu tun ist, wenn eine Bedingung erfüllt ist. Wenn in der folgenden API-Proxy-XML eine GET-Anfrage an https://yourorg-test.apigee.net/mygreatweatherforecast/reports
gesendet wird, führt Edge in der Antwort die Richtlinie „XML-zu-JSON-1“ aus.
<Flows> <Flow name="reports"> <Description/> <Request/> <Response> <Step> <Name>XML-to-JSON-1</Name> </Step> </Response> <Condition>(proxy.pathsuffix MatchesPath "/reports") and (request.verb = "GET")</Condition> </Flow>
Zusätzlich zu diesen optionalen bedingten Abläufen enthält jeder API-Proxy auch zwei Standardabläufe: einen <PreFlow>
, der vor den bedingten Abläufen ausgeführt wird, und einen <PostFlow>
, der nach den bedingten Abläufen ausgeführt wird. Diese sind nützlich, um Richtlinien auszuführen, wenn ein beliebiger Aufruf an einen API-Proxy erfolgt. Wenn Sie beispielsweise den API-Schlüssel einer Anwendung bei jedem Aufruf prüfen möchten, können Sie unabhängig vom Zugriff auf die Backend-Ressource eine Richtlinie zum Prüfen des API-Schlüssels im <PreFlow>
bereitstellen. Weitere Informationen zu Abläufen finden Sie unter Abläufe konfigurieren.
Bedingte Abläufe für Backend-Ressourcen erstellen
Das Definieren bedingter Abläufe für Backend-Ressourcen in einem API-Proxy ist optional. Mit diesen bedingten Abläufen haben Sie jedoch die Möglichkeit, differenzierte Verwaltungs- und Monitoringaufgaben auszuführen.
Sie haben folgende Möglichkeiten:
- Verwaltungsaufgaben an die Semantik Ihres API-Modells anpassen
- Richtlinien und skriptbasiertes Verhalten auf einzelne Ressourcenpfade (URIs) anwenden
- Detaillierte Messwerte für Analytics-Dienste erfassen
Stellen Sie sich beispielsweise vor, Sie müssen verschiedene Arten von Logik auf Ihr Back-End anwenden. /developers zu /apps-Ressourcen.
Fügen Sie dazu Ihrem API-Proxy zwei bedingte Abläufe hinzu: /developers
und /apps
.
Klicken Sie in der Ansicht „Develop“ des API-Proxy-Editors auf + neben „default“ unter „Proxy Endpoints“.
In diesem Fenster geben Sie die folgenden Schlüsselkonfigurationen ein:
- Flow name: Developers
- Condition Type: Path
- Path: /developers
Die Bedingung wird ausgelöst (und Richtlinien werden ausgeführt), wenn ein Aufruf mit /developers am Ende des URI an den Proxy gesendet wird.
Fügen Sie nun einen bedingten Ablauf für /apps hinzu. Nehmen Sie an, dass die Bedingung sowohl für den URI als auch für das POST-Verb in einer Anfrage ausgelöst werden soll. Die Konfiguration umfasst Folgendes:
- Flow Name: Apps
- Condition Type: Path and Verb
- Pfad: /apps
- Verb:: POST
Die Bedingung wird ausgelöst (und Richtlinien werden ausgeführt), wenn ein Aufruf mit /apps am Ende des URI und einem POST-Verb an den Proxy gesendet wird.
Im Navigationsbereich werden neue Abläufe für Apps und Developers angezeigt.
Wählen Sie einen der Abläufe aus, um die Konfiguration des bedingten Ablaufs in der Codeansicht des API-Proxy-Editors aufzurufen:
<Flow name="Apps"> <Description>Developer apps registered in Developer Services</Description> <Request/> <Response/> <Condition>(proxy.pathsuffix MatchesPath "/apps") and (request.verb = "POST")</Condition> </Flow>
API-Ressourcen sind einfach nur bedingte Abläufe, die den URI-Pfad der eingehenden Anfrage auswerten. Die Variable „proxy.pathsuffix“ gibt den URI der Anfrage an, der dem in der ProxyEndpoint-Konfiguration konfigurierten BasePath entspricht.
Jede von Ihnen definierte API-Ressource wird durch einen bedingten Ablauf im API-Proxy implementiert. (Siehe Abläufe konfigurieren)
Nachdem Sie den API-Proxy in der Testumgebung bereitgestellt haben, führt die folgende Abfrage
http://{org_name}-test.apigee.net/{proxy_path}/apps
dazu, dass die Bedingung zu „true“ ausgewertet und dieser Ablauf zusammen mit allen zugehörigen Richtlinien ausgeführt wird.
Die folgende Beispielbedingung verwendet einen regulären Java-Ausdruck, um Aufrufe für die Ressource /apps
mit oder ohne abschließendem Schrägstrich (/apps
oder /apps/**
) zu erkennen:
<Condition>(proxy.pathsuffix JavaRegex "/apps(/?)") and (request.verb = "POST")</Condition>
Weitere Informationen zu diesem Bedingungstyp finden Sie unter How to match regardless ... in der Apigee-Community.
Hierarchische URIs modellieren
In einigen Fällen stehen hierarchische API-Ressourcen zur Verfügung. Beispielsweise bietet die Developer Services API eine Methode zum Auflisten aller Anwendungen, die zu einem Entwickler gehören. Der URI-Pfad lautet:
/developers/{developer_email}/apps
Möglicherweise gibt es Ressourcen, bei denen für jede Entität in einer Sammlung eine eindeutige ID generiert wird, die manchmal so annotiert wird:
/genus/:id/species
Dieser Pfad wird gleichermaßen auf die folgenden beiden URIs angewendet:
/genus/18904/species /genus/17908/species
Um diese Struktur in einer API-Ressource darzustellen, können Sie Platzhalter verwenden. Beispiel:
/developers/*/apps
/developers/*example.com/apps
/genus/*/species
löst diese hierarchischen URIs als entsprechende API-Ressourcen auf.
In einigen Fällen, insbesondere bei hierarchischen APIs, können Sie auch alles unter einem bestimmten URI-Fragment auflösen. Verwenden Sie dazu einen doppelten Sternchenplatzhalter in Ihrer Ressourcendefinition. Angenommen, Sie definieren die folgende API-Ressource:/developers/**
Diese API-Ressource löst die folgenden URI-Pfade auf:
/developers/{developer_email}/apps /developers/{developer_email}/keys /developers/{developer_email}/apps/{app_id}/keys
So sieht die Bedingung für den bedingten Ablauf in der API-Proxy-Definition aus:
<Condition>(proxy.pathsuffix MatchesPath "/developers/**") and (request.verb = "POST")</Condition>
Weitere Beispiele
Mit einer Routingregel verknüpfte Bedingung
<RouteRule name="default">
<!--this routing executes if the header indicates that this is an XML call. If true, the call is routed to the endpoint XMLTargetEndpoint-->
<Condition>request.header.content-type = "text/xml"</Condition>
<TargetEndpoint>XmlTargetEndpoint</TargetEndpoint>
</RouteRule>
Mit einer Richtlinie verknüpfte Bedingung
<Step> <!--the policy MaintenancePolicy only executes if the response status code is exactly 503--> <Condition>response.status.code = 503</Condition> <Name>MaintenancePolicy</Name> </Step>
Bedingter Ablauf
<!-- this entire flow is executed only if the request verb is a GET--> <Flow name="GetRequests"> <Condition>request.verb="GET"</Condition> <Request> <Step> <!-- this policy only executes if request path includes a term like statues--> <Condition>request.path ~ "/statuses/**"</Condition> <Name>StatusesRequestPolicy</Name> </Step> </Request> <Response> <Step> <!-- this condition has multiple expressions. The policy executes if the response code status is exactly 503 or 400--> <Condition>(response.status.code = 503) or (response.status.code = 400)</Condition> <Name>MaintenancePolicy</Name> </Step> </Response> </Flow>
Beispieloperatoren in Bedingungen
Beispiele für Operatoren zum Erstellen von Bedingungen:
request.header.content-type = "text/xml"
request.header.content-length < 4096 && request.verb = "PUT"
response.status.code = 404 || response.status.code = 500
request.uri MatchesPath "/*/statuses/**"
request.queryparam.q0 NotEquals 10
Praktisches Beispiel: „/“ am Ende eines Pfads ignorieren
Edge-Entwickler möchten in der Regel beide Pfadsuffixe verarbeiten: „/cat
“ und „/cat/
“. Dies liegt daran, dass manche Nutzer oder Clients Ihre API mit dem zusätzlichen Schrägstrich am Ende des Pfads aufrufen und Sie in der Lage sein müssen, dies in Ihren bedingten Anweisungen zu berücksichtigen. Dieser Anwendungsfall wurde in der Apigee-Community diskutiert.
Sie können dies auch ohne Regex erreichen. Gehen Sie dazu so vor:
<PreFlow name="PreFlow"> <Request> <Step> <Condition>((proxy.pathsuffix = "/cat") OR (proxy.pathsuffix = "/cat/")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
Das ist eine gute Option. Sie ist gut verständlich und lesbar.
Sie können dies auch mit Regex erreichen. Gehen Sie dazu so vor. Die Klammern können zum Gruppieren des regulären Ausdrucks der Anweisung verwendet werden, sind aber nicht erforderlich.
<Condition>(proxy.pathsuffix JavaRegex "/cat(/?)"</Condition>
API-Aufrufe:
GET http://artomatic-test.apigee.net/matchtest/cat
or
GET http://artomatic-test.apigee.net/matchtest/cat
/
Wird die Richtlinie ausgeführt? Ja. Beachten Sie, dass in einem regulären Ausdruck der "?
"
bedeutet: entspricht null oder einem der vorangehenden Zeichen. Daher sind sowohl
„/cat
“ und "/cat/
" sind Übereinstimmungen.
API-Aufruf:
GET http://artomatic-test.apigee.net/matchtest/cat/spotted
Wird die Richtlinie ausgeführt? Nein. Der reguläre Ausdruck entspricht null oder nur einem Vorkommen des vorherigen Zeichens und nichts anderes ist zulässig.
Beliebige Strings mit JavaRegex abgleichen
In allen Beispielen in diesem Thema wird gezeigt, wie Sie eine der integrierten Flussvariablen abgleichen können: proxy.pathsuffix. Es ist gut zu wissen, dass Sie den Musterabgleich für jeden beliebigen String oder jede Variable machen können, unabhängig davon, ob es sich um eine integrierte Ablaufvariable wie proxy.pathsuffix handelt.
Wenn Sie beispielsweise eine Bedingung haben, mit der beliebige Strings getestet werden, z. B. ein String, der in einer Backend-Nutzlast zurückgegeben wird, oder ein String, der von einer Authentifizierungsserversuche zurückgegeben wird, können Sie übereinstimmende Operatoren zum Testen verwenden. Wenn Sie JavaRegex verwenden, wird der reguläre Ausdruck mit dem gesamten Substring verglichen. Wenn der Betreff „abc” lautet und der reguläre Ausdruck „[a-z]” ist, gibt es keine Übereinstimmung, da „[a-z]” genau mit einem alphanumerischen Zeichen übereinstimmt. Der Ausdruck „[a-z]+” funktioniert ebenso wie „[a-z]*” und „[a-z]{3}”.
Sehen wir uns ein konkretes Beispiel an. Angenommen, der Authentifizierungsserver gibt eine Liste von Rollen als kommagetrennten String zurück: „editor, author, guest”.
Um das Vorhandensein der editor-Rolle zu testen, funktioniert diese Konstruktion nicht, da „editor“ nur ein Teil des gesamten Strings ist.
<Condition>returned_roles ~~ "editor"</Condition>
Diese Konstruktion funktioniert jedoch:
<Condition>returned_roles ~~ ".*\beditor\b.*")</Condition>
Sie funktioniert, da sie Worttrennungen und andere Teile des Strings mit dem Präfix „.*“ und dem Suffix berücksichtigt.
In diesem Beispiel können Sie auch mit dem Matches-Operator nach „editor“ suchen:
<Condition>returned_roles ~~ "*editor*")</Condition>
Wenn Sie hingegen eine höhere Genauigkeit benötigen, ist JavaRegex häufig die bessere Wahl.
Doppelte Anführungszeichen in JavaRegex-Ausdrücken maskieren
Für die Bedingungssyntax muss ein JavaRegex-Ausdruck in doppelte Anführungszeichen gesetzt werden. Wenn Sie also einen regulären Ausdruck mit doppelten Anführungszeichen haben, benötigen Sie eine alternative Methode, um sie abzugleichen. Die Antwort lautet Unicode. Angenommen, Sie übergeben einen Header, der doppelte Anführungszeichen enthält:-H 'content-type:multipart/related; type="application/xop+xml"'Wenn Sie versuchen, diesen Header in einer Regex-Bedingung zuzuordnen, erhalten Sie einen Fehler „Ungültige Bedingung“, da der Ausdruck enthält die doppelten Anführungszeichen:
request.header.Content-Type ~~ "(multipart\/related)(; *type="application\/xop\+xml\")"Die Lösung besteht darin, die ASCII-basierten doppelten Anführungszeichen durch ihre Unicode-Entsprechung
\u0022
zu ersetzen. Beispiel:
ist der folgende Ausdruck gültig und führt zum erwarteten Ergebnis:
request.header.Content-Type ~~ "(multipart\/related)(; *type=\u0022application\/xop\+xml\u0022)"