Warunki ze zmiennymi przepływu

Wyświetlasz dokumentację Apigee Edge.
Zapoznaj się z dokumentacją Apigee X. info

Instrukcje warunkowe są powszechną strukturą sterującą we wszystkich językach programowania. Podobnie jak język programowania, konfiguracja serwera proxy interfejsu API obsługuje instrukcje warunkowe dla elementów Flows, Policies, Steps i RouteRules. Definiując instrukcje warunkowe, określasz dynamiczne zachowanie interfejsu API. To dynamiczne działanie umożliwia na przykład konwertowanie XML na JSON tylko na urządzeniach mobilnych lub kierowanie do adresu URL backendu na podstawie typu treści lub czasownika HTTP w wiadomości żądania.

Z tego artykułu dowiesz się, jak używać warunków do dynamicznego stosowania funkcji zarządzania interfejsami API w czasie działania bez pisania kodu.

Konfigurowanie instrukcji warunkowych

Zachowanie warunkowe jest implementowane w proxy interfejsów API za pomocą kombinacji warunkówzmiennych. Instrukcja warunkowa jest tworzona za pomocą elementu Condition. Poniżej znajduje się pusty warunek:

<Condition></Condition>

Aby utworzyć instrukcję warunkową, dodaj operator warunkowy i zmienną, aby utworzyć tę strukturę:

<Condition>{variable.name}{operator}{"value"}</Condition>

Obsługiwane operatory warunkowe to = (równa się), != (nie równa się) i > (większe niż). Aby zwiększyć czytelność, możesz też zapisać warunki w formie tekstu: equals, notequals, greaterthan.

Podczas pracy ze ścieżkami URI możesz używać znaków ~/ lub MatchesPath. Możesz też dopasowywać wyrażenia regularne JavaRegex za pomocą operatora ~~.

Warunki służą do definiowania przepływów warunkowych proxy interfejsu API do zasobów backendu interfejsu API, co opisano w artykule Tworzenie przepływów warunkowych do zasobów backendu interfejsu API. Pełną listę warunków znajdziesz w dokumentacji warunków.

Zmienne

Warunki działają poprzez ocenę wartości zmiennych. Zmienna to właściwość transakcji HTTP wykonywanej przez proxy interfejsu API lub właściwość samej konfiguracji proxy interfejsu API. Gdy serwer proxy interfejsu API otrzyma żądanie z aplikacji, Apigee Edge wypełnia długą listę zmiennych powiązanych z takimi elementami jak czas systemowy, informacje o sieci aplikacji, nagłówki HTTP w wiadomościach, konfiguracja serwera proxy interfejsu API, wykonania zasad itp. W ten sposób powstaje bogaty kontekst, którego możesz użyć do skonfigurowania instrukcji warunkowych.

Zmienne zawsze używają notacji z kropką. Na przykład nagłówki HTTP w wiadomości z żądaniem są dostępne jako zmienne o nazwie request.header.{header_name}. Aby ocenić nagłówek Content-type, możesz użyć zmiennej request.header.Content-type. Na przykład request.header.Content-type = "application/json" oznacza, że typ treści żądania powinien być JSON.

Załóżmy, że musisz utworzyć instrukcję warunkową, która spowoduje egzekwowanie zasad tylko wtedy, gdy komunikat żądania jest typu GET. Aby utworzyć warunek, który ocenia czasownik HTTP żądania, utwórz poniższe wyrażenie warunkowe. Zmienna w tym warunku to request.verb. Wartość zmiennej to GET. Operator to =.

<Condition>request.verb = "GET"</Condition>
 Możesz też użyć:
<Condition>request.verb equals "GET"</Condition>

Edge używa takiego stwierdzenia do oceny warunków. Powyższy przykład zwraca wartość „prawda”, jeśli czasownik HTTP powiązany z żądaniem to GET. Jeśli czasownik HTTP powiązany z żądaniem to POST, instrukcja przyjmuje wartość false.

Aby włączyć dynamiczne działanie, możesz dołączać warunki do przepływów, kroków i reguł routingu.

Gdy dołączysz warunek do przepływu, utworzysz „przepływ warunkowy”. Przepływy warunkowe są wykonywane tylko wtedy, gdy warunek ma wartość „prawda”. Możesz dołączyć dowolną liczbę zasad do przepływu warunkowego. Przepływ warunkowy umożliwia tworzenie wysoce wyspecjalizowanych reguł przetwarzania wiadomości z żądaniami lub odpowiedziami, które spełniają określone kryteria.

Aby na przykład utworzyć Flow, który będzie wykonywany tylko wtedy, gdy czasownik żądania to GET:

<Flows>
  <Flow name="ExecuteForGETs">
  <Condition>request.verb="GET"</Condition>
  </Flow>
</Flows>

Aby utworzyć jeden przepływ dla żądań GET i drugi dla żądań POST:

<Flows>
  <Flow name="ExecuteForGETs">
  <Condition>request.verb="GET"</Condition>
  </Flow>
  <Flow name="ExecuteForPOSTs">
  <Condition>request.verb="POST"</Condition>
  </Flow>
</Flows>

Jak widać na poniższym przykładzie, warunek możesz zastosować do samego kroku zasady. Poniższy warunek powoduje, że zasady VerifyApiKey są egzekwowane tylko wtedy, gdy żądanie jest typu POST.

<PreFlow name="PreFlow">
    <Request>
        <Step>
            <Condition>request.verb equals "POST"</Condition>
            <Name>VerifyApiKey</Name>
        </Step>
    </Request>
</PreFlow>

Po zdefiniowaniu takich przepływów warunkowych możesz dołączyć do nich zasady, dzięki czemu serwer proxy interfejsu API będzie egzekwować jeden zestaw zasad w przypadku żądań GET, a inny zestaw zasad w przypadku żądań POST.

Szczegółowe informacje znajdziesz w tych materiałach:

Przykład 1

Poniższy przykład pokazuje pojedynczy przepływ warunkowy o nazwie Convert-for-devices, skonfigurowany w przepływie odpowiedzi ProxyEndpoint. Dodaj warunek jako element do jednostki, do której się odnosi. W tym przykładzie warunek jest elementem przepływu. Dlatego przepływ będzie wykonywany, gdy instrukcja przyjmie wartość true.

<Flows>
  <Flow name="Convert-for-devices">
  <Condition>(request.header.User-Agent = "Mozilla")</Condition>
    <Response>
      <Step><Name>ConvertToJSON</Name></Step>
    </Response>
  </Flow>
</Flows>

W przypadku każdego żądania otrzymanego z aplikacji Edge przechowuje wartości wszystkich nagłówków HTTP jako zmienne. Jeśli żądanie zawiera nagłówek HTTP o nazwie User-Agent, ten nagłówek i jego wartość są przechowywane jako zmienna o nazwie request.header.User-Agent.

Na podstawie powyższej konfiguracji ProxyEndpoint Edge sprawdza wartość zmiennej request.header.User-Agent, aby określić, czy warunek ma wartość true.

Jeśli warunek jest spełniony, czyli wartość zmiennej request.header.User-Agent jest równa Mozilla, wykonywany jest przepływ warunkowy, a zasada XMLtoJSON o nazwie ConvertToJSON jest egzekwowana. W przeciwnym razie Flow nie zostanie wykonany, a odpowiedź XML zostanie zwrócona do aplikacji wysyłającej żądanie w niezmienionej postaci (w formacie XML).

Przykład 2

Użyjmy konkretnego przykładu, w którym musisz przekształcić wiadomość z odpowiedzi z XML na JSON, ale tylko w przypadku urządzeń mobilnych. Najpierw utwórz zasadę, która przekonwertuje odpowiedź z interfejsu Weather API w formacie XML na format JSON:

<XMLToJSON name="ConvertToJSON">
  <Options>
  </Options>
  <OutputVariable>response</OutputVariable>
  <Source>response</Source>
</XMLToJSON>

Powyższa konfiguracja zasad nakazuje serwerowi proxy interfejsu API pobranie wiadomości z odpowiedzią, przekonwertowanie jej z XML na JSON przy użyciu ustawień domyślnych, a następnie zapisanie wyniku w nowej wiadomości z odpowiedzią. (Jeśli konwertujesz wiadomość request z XML na JSON, po prostu ustaw obie te wartości na request).

.

Ponieważ chcesz przekonwertować odpowiedzi z XML na JSON, musisz skonfigurować przepływ odpowiedzi warunkowej, aby przeprowadzić konwersję. Aby na przykład przekonwertować wszystkie odpowiedzi z XML na JSON, zanim zostaną zwrócone do aplikacji klienckiej, skonfiguruj ten przepływ odpowiedzi ProxyEndpoint.

<Flows>
  <Flow name="Convert-for-devices">
    <Response>
      <Step><Name>ConvertToJSON</Name></Step>
    </Response>
  </Flow>
</Flows>

Gdy wywołasz interfejs API za pomocą standardowego żądania, odpowiedź zostanie sformatowana w formacie JSON.

Chcesz jednak przekształcać raporty pogodowe w JSON tylko wtedy, gdy klient wysyłający żądanie jest urządzeniem mobilnym. Aby włączyć takie dynamiczne działanie, musisz dodać do przepływu instrukcję warunkową.

Testowanie przepływu warunkowego

W tym przykładowym żądaniu nagłówek HTTP User-Agent ma wartość Mozilla, co powoduje, że instrukcja warunkowa przyjmuje wartość „prawda”, a warunkowy przepływ Convert-for-devices jest wykonywany.

$ curl -H "User-Agent:Mozilla" http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282

lub, aby sformatować dane w miejscu, w którym dostępny jest Python:

$ curl -H "User-Agent:Mozilla" http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282 | python -mjson.tool

Przykładowa odpowiedź:

. . .

"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"
          }
      ]
  }

. . .

Żądanie przesłane bez nagłówka User-Agent lub z wartością inną niż Mozilla spowoduje zwrócenie odpowiedzi w formacie XML.

$ curl http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282

Zwracana jest niezmodyfikowana odpowiedź XML.

Przykładowa odpowiedź:

<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" />

Dopasowywanie wzorców

W tej sekcji opisujemy, jak używać dopasowywania wzorców z warunkami w przepływie Apigee.

Operatory

W tej sekcji opisujemy, jak używać w instrukcjach warunkowych tych operatorów dopasowywania wzorców:

Dopasowania

Najpierw przyjrzyjmy się operatorowi warunkowemu „Matches” lub „~”. Te 2 operatory są takie same – wersja angielska „Matches” jest uważana za bardziej czytelną.

Podsumowanie: operator „Matches” daje 2 możliwości. Możesz dopasować ciąg znaków dosłownie lub użyć symbolu wieloznacznego „*”. Jak można się spodziewać, symbol wieloznaczny dopasowuje zero lub więcej znaków. Zobaczmy, jak to działa.

Poniższy kod XML przedstawia warunek kroku. Wykonuje zasadę SomePolicy, gdy warunek ma wartość „prawda”. W tym przykładzie testujemy zmienną proxy.pathsuffix, wbudowaną zmienną w Edge, która przechowuje sufiks ścieżki żądania. Możesz jednak przetestować wartość dowolnej zmiennej przepływu, która zawiera ciąg znaków. W tym przypadku, jeśli ścieżka podstawowa żądania przychodzącego to /animals, a żądanie to /animals/cat, sufiks ścieżki to ciąg znaków „/cat”.

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>(proxy.pathsuffix Matches "/cat")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

Pytanie: jaki sufiks ścieżki serwera proxy spowoduje wykonanie zasady SomePolicy? Jest tylko jedna możliwość.

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Tak, ponieważ sufiks ścieżki proxy jest dokładnie zgodny z wartością „/cat”. Nie zostanie wykonana, jeśli sufiks to /bat lub /dog albo „/” lub cokolwiek innego.

Rozważmy teraz instrukcję warunkową, w której używamy symbolu wieloznacznego „*”:

<Condition>(proxy.pathsuffix Matches "/*at")</Condition>

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Tak, ponieważ symbol wieloznaczny pasuje do dowolnego znaku, a "/cat jest dopasowaniem.

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Tak, ponieważ symbol wieloznaczny pasuje do dowolnego znaku, więc "/bat" jest dopasowaniem.

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Nie, ponieważ symbol wieloznaczny pasuje do znaku „o”, ale litery „wl” nie pasują.

Teraz przenieśmy symbol wieloznaczny na koniec sufiksu:

<Condition>(proxy.pathsuffix Matches "/cat*")</Condition>

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Tak, ponieważ symbol wieloznaczny dopasowuje zero lub więcej dowolnych znaków.

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Nie, „/bat” nie pasuje.

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Tak, symbol wieloznaczny dopasowuje zero lub więcej dowolnych znaków, więc „123” daje dopasowanie.

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Tak, ponieważ symbol wieloznaczny dopasowuje zero lub więcej dowolnych znaków, więc „/bird/mouse” daje dopasowanie. Zwróć uwagę, że takie wyrażenie może sprawić Ci kłopoty, ponieważ pasuje do wszystkiego, co znajduje się po znakach literalnych.

Pytanie: czy w przypadku operatora „Pasuje do” rozróżniana jest wielkość liter?

Tak. Załóżmy, że masz taki warunek:

<Condition>(proxy.pathsuffix Matches "/*At")</Condition>

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Nie. Symbol wieloznaczny pasuje do każdej litery (niezależnie od wielkości), ale mała litera „a” nie pasuje do wielkiej litery „A”.

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Tak, wielkość liter jest zgodna.

Pytanie: Jak mogę użyć znaku zmiany znaczenia w przypadku operatora Matches?

Aby zmienić znaczenie znaków zarezerwowanych, użyj znaku procenta „%”. Na przykład:

<Condition>(proxy.pathsuffix Matches "/c%*at")</Condition>

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Nie, operator Matches szuka dosłownego ciągu znaków „c*at”.

Wywołanie interfejsu API:

GET http://artomatic-test.apigee.net/matchtest/c*at

Pytanie:czy zasady są wykonywane?

Tak, ta ścieżka, choć nieco nietypowa, pasuje.

JavaRegex

Jak widać, operator „Matches” sprawdza się w prostych sytuacjach. Możesz jednak użyć innego operatora, np. „JavaRegex” lub „~~”. Są to te same operatory, z tym że JavaRegex jest uważany za bardziej czytelny. Nazywa się JavaRegex, ponieważ umożliwia dopasowywanie wzorców wyrażeń regularnych, a Edge przestrzega tych samych reguł co klasy w pakiecie java.util.regex w języku Java. Działanie operatora JavaRegex bardzo różni się od działania operatora Matches, więc nie należy ich mylić.

Podsumowanie: operator „JavaRegex” umożliwia używanie składni wyrażeń regularnych w instrukcjach warunkowych.

Poniższy kod przedstawia warunek kroku. Jeśli warunek przyjmie wartość true (prawda), zostanie wykonana zasada SomePolicy. W tym przykładzie testujemy zmienną proxy.pathsuffix, wbudowaną zmienną w Edge, która przechowuje sufiks ścieżki żądania. Jeśli ścieżka podstawowa żądania przychodzącego to /animals, a żądanie to /animals/cat, to sufiks ścieżki jest ciągiem znaków „/cat”.

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>(proxy.pathsuffix JavaRegex "/cat")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

Pytanie: jaki sufiks ścieżki serwera proxy spowoduje wykonanie zasady SomePolicy? Podobnie jak w przypadku operatora „Pasuje”, w tym przypadku jest tylko jedna możliwość.

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Tak, ponieważ sufiks ścieżki proxy jest dokładnie zgodny z wartością „/cat”. Nie zostanie wykonane, jeśli sufiks to /bat lub /dog albo cokolwiek innego.

Teraz utwórzmy wyrażenie regularne z kwantyfikatorem „*”. Ten kwantyfikator dopasowuje zero lub więcej wystąpień poprzedniego znaku.

<Condition>(proxy.pathsuffix JavaRegex "/c*t")</Condition>

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Nie! Kwantyfikator „*” dopasowuje zero lub więcej wystąpień poprzedzającego znaku, czyli „c”.

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Tak, ponieważ symbol wieloznaczny dopasowuje zero lub więcej poprzedzających znaków.

Następnie używamy kwantyfikatora „?”, który dopasowuje poprzedzający znak raz lub wcale.

<Condition>(proxy.pathsuffix JavaRegex "/ca?t")</Condition>

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Tak. Kwantyfikator „?” dopasowuje zero lub jedno wystąpienie poprzedniego znaku, czyli „a”.

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Tak. Kwantyfikator „?” dopasowuje jeden lub żaden z poprzedzających znaków. W tym przypadku nie ma znaku „a”, więc warunek przyjmuje wartość „true”.

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Nie. Kwantyfikator „?” dopasowuje jeden z poprzednich znaków, czyli „a”.

Następnie używamy stylu wyrażenia regularnego „[abc]” lub „grupowanie”. Odpowiada znakom „a”, „b” lub „c”.

<Condition>(proxy.pathsuffix JavaRegex "/[cbr]at")</Condition>

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Tak. Używamy tu wyrażeń regularnych, a wyrażenie „[cbr]” pasuje do litery „c”, „b” LUB „r”. Dopasowania te obejmują też:

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

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

Ale to nie jest dopasowanie:

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

Pytanie: czy w przypadku operatora JavaRegex jest rozróżniana wielkość liter?

Tak. Załóżmy, że masz taki warunek:

<Condition>(proxy.pathsuffix JavaRegex "/ca?t")</Condition>

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Tak, wyrażenie regularne dopasowuje zero lub jedno wystąpienie poprzedniego znaku, czyli „a”.

Wywołanie interfejsu API:

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

Pytanie: czy zasady są wykonywane?

Nie, ponieważ wielka litera „A” nie pasuje do małej litery „a”.

MatchesPath

Operator MatchesPath można też zapisać jako „~/”. Wygląda on podobnie do operatorów Matches (~) i JavaRegex (~~). Funkcja MatchesPath działa jednak zupełnie inaczej.

Pamiętaj, że ten operator traktuje ścieżkę jako serię części. Jeśli więc ścieżka to /animals/cats/wild, możesz ją traktować jako składającą się z części „/animals”, „/cats” i „/wild”.

Operator MatchesPath umożliwia używanie 2 rodzajów symboli wieloznacznych: pojedynczej gwiazdki (*) i podwójnej gwiazdki (**). Pojedyncza gwiazdka pasuje do 1 elementu ścieżki. Podwójny asterisk pasuje do co najmniej 1 elementu ścieżki.

Przeanalizujmy poniższy przykład. W tym przykładzie testujemy zmienną proxy.pathsuffix, wbudowaną zmienną w Edge, która przechowuje sufiks ścieżki żądania. Możesz jednak przetestować wartość dowolnej zmiennej przepływu, która zawiera ciąg znaków.

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>(proxy.pathsuffix MatchesPath "/animals/*")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

Pytanie: jaki sufiks ścieżki serwera proxy spowoduje wykonanie zasady SomePolicy?

Wywołanie interfejsu API:

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

Pytanie: czy zasady są wykonywane?

Nie, ponieważ warunek wymaga innego elementu ścieżki po znaku „/animals”, zgodnie z określeniem „/*”.

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Tak, ścieżka zawiera inny element ścieżki (część po „/animals/”), ale jest on pusty.

Wywołanie interfejsu API:

GET http://artomatic-test.apigee.net/matchtest/animals/cats

Czy zasada jest wykonywana? Tak, ponieważ ścieżka zawiera element („/cats”), który występuje po „/animals

Wywołanie interfejsu API:

GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild

Pytanie: czy zasady są wykonywane?

Nie, ponieważ pojedynczy znak gwiazdki pasuje tylko do 1 elementu ścieżki, a ten interfejs API ma więcej niż 1 element po „/animals”.

Teraz użyjmy podwójnego asterisku:

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>(proxy.pathsuffix MatchesPath "/animals/**")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

Pytanie: jaki sufiks ścieżki serwera proxy spowoduje wykonanie zasady SomePolicy?

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Nie, ponieważ warunek wymaga co najmniej 1 elementu ścieżki określonego przez „/**”.

Wywołanie interfejsu API:

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

Czy zasady są wykonywane?

Tak, ścieżka zawiera inny element ścieżki (część po „/animals/”), ale jest on pusty.

Wywołanie interfejsu API:

GET http://artomatic-test.apigee.net/matchtest/animals/cats

Czy zasady są wykonywane?

Tak, ponieważ ścieżka zawiera co najmniej 1 element, który występuje po znaku „/animals”.

Wywołanie interfejsu API:

GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild

Czy zasady są wykonywane?

Tak, ponieważ ścieżka zawiera więcej niż 1 element po znaku „/animals

Mieszanie gwiazdek

Możesz używać kombinacji pojedynczej (*) i podwójnej (**) gwiazdki, aby jeszcze bardziej doprecyzować dopasowywanie ścieżek.

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>(proxy.pathsuffix MatchesPath "/animals/*/wild/**")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

Wywołanie interfejsu API:

Wszystkie te wywołania interfejsu API spowodują dopasowanie:

GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild/

i

GET http://artomatic-test.apigee.net/matchtest/animals/dogs/wild/austrailian

oraz

GET http://artomatic-test.apigee.net/matchtest/animals/birds/wild/american/finches

Zasoby interfejsu API

Usługi RESTful to zbiory zasobów interfejsu API. Zasób interfejsu API to fragment ścieżki URI, który identyfikuje jednostkę, do której programiści mogą uzyskać dostęp, wywołując Twój interfejs API. Jeśli na przykład Twoja usługa udostępnia raporty i prognozy pogody, usługa backendu może definiować 2 zasoby interfejsu API:

  • http://mygreatweatherforecast.com/reports
  • http://mygreatweatherforecast.com/forecasts

Gdy tworzysz serwer proxy interfejsu API (jak pokazano w artykule Tworzenie pierwszego serwera proxy interfejsu API), tworzysz co najmniej aliasowy podstawowy adres URL, który jest mapowany na usługę backendu. Na przykład:

Podstawowy adres URL backendu Nowy lub równoważny adres URL serwera proxy interfejsu API
http://mygreatweatherforecast.com http://{your_org}-{environment}.apigee.net/mygreatweatherforecast

Na tym etapie możesz wykonywać wywołania interfejsu API do backendu, używając dowolnego adresu URL. Jednak gdy użyjesz adresu URL serwera proxy interfejsu API, sytuacja zacznie się komplikować.

Oprócz danych analitycznych interfejsu API, które Edge zaczyna zbierać, gdy używasz serwera proxy interfejsu API, serwery proxy umożliwiają też definiowanie przepływów warunkowych, które są mapowane na zasoby na Twoim backendzie. W zasadzie oznacza to: „Jeśli do zasobu /reports przyjdzie wywołanie GET, Edge powinien coś zrobić”.

Obraz poniżej pokazuje różnicę w działaniu dwóch adresów URL, które ostatecznie uzyskują dostęp do tego samego backendu. Jeden to adres URL zasobu bez serwera proxy, a drugi to serwer proxy Edge API z przepływem warunkowym do tego samego zasobu backendu. Poniżej opisujemy szczegółowo przepływy warunkowe.

Jak serwery proxy interfejsu API są mapowane na konkretne zasoby backendu

Gdy adres URL serwera proxy API jest mapowany na podstawowy adres URL usługi backendu (podczas tworzenia serwera proxy), możesz dodawać przepływy warunkowe do określonych zasobów, takich jak zasoby /reports/forecasts wspomniane wcześniej.

Załóżmy, że chcesz, aby Edge „coś zrobił”, gdy połączenia przychodzą do zasobów /reports lub /forecasts. Na tym etapie nie mówisz Edge'owi, co ma robić, tylko że ma nasłuchiwać wywołań tych zasobów. Możesz to zrobić za pomocą warunków. W proxy interfejsu API Edge możesz tworzyć przepływy warunkowe dla /reports/forecasts. Poniższy przykładowy kod XML serwera proxy interfejsu API pokazuje, jak mogą wyglądać te warunki.

<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>

Warunki te mówią: „Gdy nadejdzie żądanie GET z /reports/forecasts w adresie URL, Edge wykona wszystko, co mu powiesz (jako deweloper interfejsu API) za pomocą zasad dołączonych do tych przepływów.

Oto przykład, jak poinformować Edge o tym, co ma zrobić po spełnieniu warunku. W tym przykładowym pliku XML serwera proxy interfejsu API, gdy żądanie GET jest wysyłane do https://yourorg-test.apigee.net/mygreatweatherforecast/reports, Edge wykonuje w odpowiedzi zasadę „XML-to-JSON-1”.

<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>

Oprócz tych opcjonalnych przepływów warunkowych każdy serwer proxy interfejsu API ma też 2 domyślne przepływy: <PreFlow> wykonywany przed przepływami warunkowymi i <PostFlow> wykonywany po nich. Są one przydatne do wykonywania zasad, gdy do serwera proxy interfejsu API jest wysyłane dowolne wywołanie. Jeśli na przykład chcesz weryfikować klucz interfejsu API aplikacji przy każdym wywołaniu, niezależnie od tego, do którego zasobu backendu uzyskuje się dostęp, możesz umieścić zasadę Verify API Key (Weryfikuj klucz interfejsu API) w <PreFlow>. Więcej informacji o przepływach znajdziesz w artykule Konfigurowanie przepływów.

Tworzenie przepływów warunkowych do zasobów backendu

Definiowanie przepływów warunkowych do zasobów backendu w proxy interfejsu API jest całkowicie opcjonalne. Te przepływy warunkowe umożliwiają jednak precyzyjne zarządzanie i monitorowanie.

Możesz:

  • Stosowanie zarządzania w sposób odzwierciedlający semantykę modelu interfejsu API
  • Stosowanie zasad i skryptów do poszczególnych ścieżek zasobów (identyfikatorów URI)
  • Zbieranie szczegółowych danych o usługach analitycznych

Wyobraź sobie na przykład, że musisz zastosować różne rodzaje logiki do zasobów backendu /developers i /apps.

Aby to zrobić, dodaj do serwera proxy interfejsu API 2 przepływy warunkowe: /developers/apps.

W widoku Develop (Tworzenie) w panelu Navigator (Nawigator) edytora proxy interfejsu API kliknij ikonę + obok opcji default w sekcji Proxy Endpoints (Punkty końcowe proxy).

W oknie „Nowy przepływ warunkowy” wpisz te konfiguracje kluczy:

  • Nazwa przepływu: Deweloperzy
  • Typ warunku: ścieżka
  • Ścieżka: /developers

Warunek zostanie uruchomiony (a zasady zostaną wykonane), jeśli połączenie zostanie wysłane do serwera proxy z dopiskiem /developers na końcu URI.

Teraz dodaj przepływ warunkowy dla /apps i załóż, że warunek ma być wywoływany zarówno w przypadku identyfikatora URI, jak i czasownika POST w żądaniu. Konfiguracja obejmuje ustawienie tych elementów:

  • Nazwa przepływu: Aplikacje
  • Typ warunku: ścieżka i czasownik
  • Ścieżka: /apps
  • Czasownik: POST

Warunek zostanie uruchomiony (a zasady zostaną wykonane), jeśli do serwera proxy zostanie wysłane wywołanie z końcówką URI /apps i czasownikiem POST.

W panelu Nawigator zobaczysz nowe ścieżki dla aplikacjiprogramistów.

Wybierz jeden z przepływów, aby wyświetlić konfigurację przepływu warunkowego w widoku kodu edytora proxy interfejsu API:

<Flow name="Apps">
    <Description>Developer apps registered in Developer Services</Description>
    <Request/>
    <Response/>
    <Condition>(proxy.pathsuffix MatchesPath "/apps") and (request.verb = "POST")</Condition>
</Flow>

Jak widać, zasoby interfejsu API to po prostu przepływy warunkowe, które oceniają ścieżkę URI żądania przychodzącego. (Zmienna proxy.pathsuffix identyfikuje identyfikator URI żądania, który następuje po ścieżce BasePath skonfigurowanej w konfiguracji ProxyEndpoint).

Każdy zdefiniowany zasób interfejsu API jest implementowany przez warunkowy przepływ w proxy interfejsu API. (Patrz Konfigurowanie przepływów).

Po wdrożeniu proxy interfejsu API w środowisku testowym to żądanie:

http://{org_name}-test.apigee.net/{proxy_path}/apps

spowoduje, że warunek zostanie uznany za prawdziwy, a ten przepływ wraz z wszelkimi powiązanymi zasadami zostanie wykonany.

Poniższy przykład warunku używa wyrażenia regularnego w języku Java do rozpoznawania wywołań zasobu /apps z ukośnikiem na końcu lub bez niego (/apps lub /apps/**):

<Condition>(proxy.pathsuffix JavaRegex "/apps(/?)") and (request.verb = "POST")</Condition>

Więcej informacji o tym typie warunku znajdziesz w artykule How to match regardless ... (Jak dopasowywać niezależnie od...) w Społeczności Apigee.

Modelowanie hierarchicznych identyfikatorów URI

W niektórych przypadkach będziesz mieć hierarchiczne zasoby interfejsu API. Na przykład interfejs Developer Services API udostępnia metodę wyświetlania wszystkich aplikacji należących do dewelopera. Ścieżka identyfikatora URI to:

/developers/{developer_email}/apps

Możesz mieć zasoby, w których dla każdego elementu w kolekcji generowany jest unikalny identyfikator. Czasami jest to oznaczane w ten sposób:

/genus/:id/species

Ta ścieżka dotyczy w równym stopniu tych 2 identyfikatorów URI:

/genus/18904/species
/genus/17908/species

Aby przedstawić tę strukturę w zasobie interfejsu API, możesz użyć symboli wieloznacznych. Na przykład:

/developers/*/apps
/developers/*example.com/apps
/genus/*/species

będzie odpowiednio rozpoznawać te hierarchiczne identyfikatory URI jako zasoby interfejsu API.

W niektórych przypadkach, zwłaszcza w przypadku interfejsów API o głębokiej hierarchii, możesz po prostu chcieć rozwiązać wszystko poniżej określonego fragmentu URI. Aby to zrobić, użyj w definicji zasobu symbolu wieloznacznego w postaci dwóch gwiazdek. Jeśli na przykład zdefiniujesz to zasób interfejsu API:
/developers/**

Ten zasób interfejsu API będzie rozpoznawać te ścieżki URI:

/developers/{developer_email}/apps
/developers/{developer_email}/keys
/developers/{developer_email}/apps/{app_id}/keys

Oto jak warunek przepływu warunkowego wyglądałby w definicji serwera proxy interfejsu API:

<Condition>(proxy.pathsuffix MatchesPath "/developers/**") and (request.verb = "POST")</Condition>

Więcej przykładów

Warunek dołączony do RouteRule

<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>

Warunek dołączony do zasady

<Step>
<!--the policy MaintenancePolicy only executes if the response status code is exactly 503-->
  <Condition>response.status.code = 503</Condition>
  <Name>MaintenancePolicy</Name>
</Step>

Przepływ warunkowy

<!-- 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>

Przykładowe operatory w warunkach

Oto kilka przykładów operatorów używanych do tworzenia warunków:

  • 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

Praktyczny przykład: ignorowanie znaku „/” na końcu ścieżki

Deweloperzy Edge często chcą obsługiwać oba te sufiksy ścieżki: „/cat” i „/cat/”. Dzieje się tak, ponieważ niektórzy użytkownicy lub klienci mogą wywoływać interfejs API z dodatkowym ukośnikiem na końcu ścieżki, a Ty musisz być w stanie obsłużyć to w instrukcjach warunkowych. Ten konkretny przypadek użycia został omówiony na forum społeczności Apigee.

Możesz to zrobić bez używania wyrażeń regularnych, np. tak:

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>((proxy.pathsuffix = "/cat") OR (proxy.pathsuffix = "/cat/")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

To dobra opcja. jest wyraźny i czytelny;

Możesz to zrobić za pomocą wyrażeń regularnych w ten sposób: Nawiasy służą do grupowania części wyrażenia regularnego, ale nie są wymagane.

<Condition>(proxy.pathsuffix JavaRegex "/cat(/?)"</Condition>

Wywołania interfejsu API:

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

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

Czy zasada jest wykonywana? Tak. Pamiętaj, że w wyrażeniu regularnym znak „?” oznacza: dopasuj zero lub 1 poprzedni znak. Dlatego pasują zarówno „/cat”, jak i „/cat/”.

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Nie. Wyrażenie regularne pasuje do zera lub tylko jednego wystąpienia poprzedzającego znaku i niczego więcej.

Dopasowywanie dowolnych ciągów znaków za pomocą funkcji JavaRegex

We wszystkich przykładach w tym temacie pokazujemy, jak dopasować jedną z wbudowanych zmiennych przepływu: proxy.pathsuffix. Warto wiedzieć, że dopasowywanie wzorców można przeprowadzać w przypadku dowolnego ciągu znaków lub zmiennej przepływu, niezależnie od tego, czy jest to wbudowana zmienna przepływu, np. proxy.pathsuffix.

Jeśli na przykład masz warunek, który testuje dowolny ciąg znaków, np. ciąg znaków zwrócony w ładunku backendu lub ciąg znaków zwrócony z wyszukiwania na serwerze uwierzytelniania, możesz użyć operatorów dopasowywania, aby go przetestować. Jeśli używasz JavaRegex, wyrażenie regularne będzie porównywane z całym ciągiem znaków tematu. Jeśli temat to „abc”, a wyrażenie regularne to „[a-z]”, nie ma dopasowania, ponieważ „[a-z]” pasuje dokładnie do jednego znaku alfabetycznego. Wyrażenie „[a-z]+” działa tak samo jak „[a-z]*” i „[a-z]{3}.

Przeanalizujmy to na konkretnym przykładzie. Załóżmy, że serwer uwierzytelniania zwraca listę ról w postaci ciągu rozdzielonego przecinkami: „editor, author, guest”.

Aby sprawdzić, czy występuje rola edytującego, ta konstrukcja nie zadziała, ponieważ „edytujący” jest tylko częścią całego ciągu znaków.

<Condition>returned_roles ~~ "editor"</Condition>

Ta konstrukcja będzie jednak działać:

<Condition>returned_roles ~~ ".*\beditor\b.*")</Condition>

Działa to dlatego, że uwzględnia podziały wyrazów i wszystkie inne części ciągu znaków z prefiksem i sufiksem .*.

W tym przykładzie możesz też sprawdzić, czy występuje „edytujący”, za pomocą operatora Pasuje:

<Condition>returned_roles ~~ "*editor*")</Condition>

Jeśli jednak potrzebujesz większej precyzji, JavaRegex jest często lepszym wyborem.

Używanie znaku zmiany znaczenia w przypadku podwójnych cudzysłowów w wyrażeniach JavaRegex

Składnia warunku wymaga, aby wyrażenie JavaRegex było ujęte w cudzysłów amerykański. Jeśli więc masz wyrażenie Regex, które zawiera cudzysłów amerykański, musisz znaleźć inny sposób na dopasowanie go. Odpowiedź to Unicode. Załóżmy na przykład, że przekazujesz nagłówek zawierający cudzysłowy, np. taki:
 -H 'content-type:multipart/related; type="application/xop+xml"'
Jeśli spróbujesz dopasować ten nagłówek w warunku wyrażenia regularnego, pojawi się błąd nieprawidłowego warunku, ponieważ wyrażenie zawiera podwójne cudzysłowy:
request.header.Content-Type ~~ "(multipart\/related)(; *type="application\/xop\+xml\")"
Rozwiązaniem jest zastąpienie cudzysłowów opartych na kodzie ASCII ich odpowiednikami w Unicode, czyli znakiem \u0022. Na przykład to wyrażenie jest prawidłowe i daje oczekiwany wynik:
request.header.Content-Type ~~ "(multipart\/related)(; *type=\u0022application\/xop\+xml\u0022)"