Bedingungen mit Ablaufvariablen

Sie sehen die Dokumentation zu Apigee Edge.
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 conditions und conditions 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 Anwendung erhält, füllt Apigee Edge eine lange Liste von Variablen aus, die mit Dingen wie der Systemzeit, den Netzwerkinformationen der Anwendung, HTTP-Headern für Nachrichten, der API-Proxy-Konfiguration, Richtlinienausführungen usw. verbunden sind. 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önnten 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 vorhandenen HTTP-Header als Variablen. 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 prüft Edge den Wert der Variable request.header.User-Agent, um festzustellen, ob die Bedingung als wahr ausgewertet wird.

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:

Übereinstimmungen

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, eine in Edge integrierte Variable, 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? Definitiv nicht. Obwohl der Platzhalter mit "o" übereinstimmt, werden die Buchstaben "wl" nicht zugeordnet.

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" stimmt nicht überein.

API-Aufruf:

GET http://artomatic-test.apigee.net/matchtest/cat123

Wird die Richtlinie ausgeführt? Ja, der Platzhalter entspricht null oder mehr beliebigen Zeichen, daher führt „123“ zu einer Übereinstimmung.

API-Aufruf:

GET http://artomatic-test.apigee.net/matchtest/cat/bird/mouse

Wird die Richtlinie ausgeführt? Ja, da der Platzhalter mit null oder mehr beliebigen Zeichen übereinstimmt. Daher ergibt „/bird/mouse“ eine Übereinstimmung. 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 einem beliebigen Buchstaben (unabhängig von der Groß-/Kleinschreibung), aber der kleingeschriebene „a“ entspricht nicht „A“.

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 literalen String "c*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. Er heißt JavaRegex, weil er den Musterabgleich regulärer Ausdrücke zulässt. Edge folgt denselben Regeln wie die Klassen im Paket java.util.regex 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 Richtlinie „SomePolicy“ aus, wenn die Bedingung als „true“ ausgewertet wird. In diesem Beispiel testen wir die Variable proxy.pathsuffix, eine in Edge integrierte Variable, die das Pfadsuffix der Anfrage speichert. 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 "*" stimmt mit null oder mehr dem vorherigen Zeichen überein, das ein "c" ist.

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 "?" stimmt mit keinem oder einem Vorkommen des vorherigen Zeichens überein, das ein "a" ist.

API-Aufruf:

GET http://artomatic-test.apigee.net/matchtest/ct

Wird die Richtlinie ausgeführt? Ja. Der Quantifizierer "?" stimmt mit einem oder keinem des vorangehenden Zeichens überein. In diesem Fall ist kein "a"-Zeichen vorhanden, sodass die Bedingung als wahr ausgewertet wird.

API-Aufruf:

GET http://artomatic-test.apigee.net/matchtest/caat

Wird die Richtlinie ausgeführt? Nein. Der Quantifizierer "?" stimmt mit einem der vorhergehenden Zeichen überein, bei denen es sich um ein "a" handelt.

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. Hier verwenden wir reguläre Ausdrücke und der Ausdruck „[cbr]“ stimmt mit „c“, „b“ ODER „r“ überein. 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 reguläre Ausdruck 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 in Edge integrierte Variable, 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, das nach „/animals“ steht

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, da die Bedingung mindestens ein nachfolgendes Pfadelement erfordert, das durch „/**“ angegeben ist.

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. Beispiel:

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 beginnt zu erfassen, wenn Sie den API-Proxy verwenden, können Sie mit Proxys auch bedingte Flows definieren, die den Ressourcen in Ihrem Back-End zugeordnet sind. Im Wesentlichen bedeutet das: „Wenn ein GET-Aufruf bei der Ressource /reports eingeht, sollte Edge etwas tun.“

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, das 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 von Edge eine Aktion ausführen lassen, wenn Aufrufe bei den Ressourcen /reports oder /forecasts eingehen. An diesem Punkt teilen Sie Edge nicht mit, was zu tun ist, sondern nur, dass es auf Aufrufe dieser Ressourcen warten soll. Dazu verwenden Sie Bedingungen. In Ihrem Edge API-Proxy können Sie bedingte Datenflüsse für /reports und /forecasts erstellen. 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 besagen Folgendes: „Wenn eine GET-Anfrage mit /reports und /forecasts in der URL eingeht, führt Edge über die Richtlinien, die Sie an diese Abläufe anhängen, alles aus, was Sie (der API-Entwickler) dazu auffordern.

Hier ist ein Beispiel, wie Edge angewiesen wird, 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-to-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 zum Beispiel vor, Sie müssen verschiedene Arten von Logik auf Ihre Back-End-/developers-Ressourcen auf die /apps-Ressourcen anwenden.

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. Wenn Sie beispielsweise die folgende API-Ressource definieren:
/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 üblicherweise die beiden Pfadsuffixe „/cat“ und „/cat/“ verarbeiten. Dies liegt daran, dass einige Nutzer oder Clients Ihre API möglicherweise mit dem zusätzlichen Schrägstrich am Ende des Pfads aufrufen und Sie dies in Ihren bedingten Anweisungen verarbeiten können müssen. 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. Das Zeichen „?“ in einem regulären Ausdruck bedeutet: Übereinstimmung mit null oder einem der vorangehenden Zeichen. Daher sind sowohl „/cat“ als auch „/cat/“ Ü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, wie im folgenden Beispiel:
 -H 'content-type:multipart/related; type="application/xop+xml"'
Wenn Sie versuchen, diesen Header in einer Regex-Bedingung abzugleichen, erhalten Sie den Fehler „Ungültige Bedingung“, da der Ausdruck doppelte Anführungszeichen enthält:
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. Der folgende Ausdruck ist beispielsweise gültig und erzeugt das erwartete Ergebnis:
request.header.Content-Type ~~ "(multipart\/related)(; *type=\u0022application\/xop\+xml\u0022)"