Warunki ze zmiennymi przepływu

Wyświetlasz dokumentację Apigee Edge.
Przejdź do Dokumentacja Apigee X.
informacje.

Instrukcje warunkowe to powszechna struktura kontrolna we wszystkich językach programowania. Podobne do języka programowania, konfiguracja serwera proxy API obsługuje instrukcje warunkowe dla Flows, Zasady, kroki i reguły trasy. Określając instrukcje warunkowe, definiujesz zachowanie dynamiczne interfejsu API. To dynamiczne zachowanie umożliwia np. konwertowanie danych XML na dane JSON tylko na urządzeniach mobilnych lub kierowanie do adresu URL backendu na podstawie typu treści lub czasownika HTTP żądania.

Z tego artykułu dowiesz się, jak używać warunków do dynamicznego stosowania funkcji zarządzania interfejsami API w środowiska wykonawczego bez konieczności pisania kodu.

Konfigurowanie instrukcji warunkowych

Zachowanie warunkowe jest implementowane w pośrednikach interfejsu API za pomocą kombinacji warunkówzmiennych. Zdanie warunkowe jest tworzone za pomocą elementu Warunek. Poniższy warunek jest pusty:

<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 od). Ze względu na czytelność możesz też zapisać warunki w postaci tekstu: equals, notequals, greaterthan.

Podczas pracy ze ścieżkami URI możesz użyć ~/ lub MatchesPath. Dostępne opcje do wyrażenia regularnego JavaRegex możesz też dopasować do operatora ~~.

Warunki są używane do definiowania warunkowych przepływów API serwera proxy interfejsu API do zasobów interfejsu API backendu, co opisano w artykule o tworzeniu przepływów warunkowych do zasobów interfejsu API backendu. Dla: Pełną listę warunków znajdziesz w artykule o warunkach.

Zmienne

Warunki działają, oceniając wartości zmiennych. Zmienna to właściwość transakcji HTTP wykonywanej przez serwer proxy interfejsu API lub właściwość serwera proxy interfejsu API. i samej konfiguracji. Za każdym razem, gdy serwer proxy interfejsu API otrzyma żądanie z aplikacji, Apigee Edge zapełnia pole długa lista zmiennych powiązanych z czasem systemowym, siecią aplikacji informacje, nagłówki HTTP w wiadomościach, konfiguracja serwera proxy API, uruchomienia zasad itd. Dzięki temu możesz tworzyć bogaty kontekst, który możesz wykorzystać do konfigurowania instrukcji warunkowych.

Zmienne zawsze używają zapisu z kropką. Na przykład nagłówki HTTP wiadomości żądania są dostępne jako zmienne o nazwie request.header.{header_name}. Aby więc ocenić W nagłówku typu treści możesz użyć zmiennej request.header.Content-type. Dla: przykład request.header.Content-type = "application/json" wskazuje, że treść żądania powinno być zapisane w formacie JSON.

Wyobraź sobie, że musisz utworzyć stwierdzenie warunkowe, które spowoduje, że zasada jest egzekwowane tylko wtedy, gdy wiadomość z żądaniem jest metodą GET. Do utworzenia warunku oceniającego czasownik HTTP dla żądania tworzysz instrukcję warunkową poniżej. Zmienna w tym warunku to request.verb Wartość zmiennej wynosi GET. Operatorem jest =

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

Edge używa takiego oświadczenia do oceny warunków. W tym przykładzie zwracamy wartość prawda, jeśli Czasownik HTTP powiązany z żądaniem to GET. Jeśli czasownik HTTP powiązany z żądaniem to POST, instrukcja zwraca wartość false (fałsz).

Aby włączyć zachowanie dynamiczne, możesz dołączyć warunki do przepływów, kroków i reguł tras.

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

Aby na przykład utworzyć przepływ, który wykonuje się 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 inny dla POST:

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

Jak widać w przykładzie poniżej, możesz zastosować warunek do samego kroku w zasadzie. Poniższy warunek powoduje, że zasada VerifyApiKey jest egzekwowana tylko wtedy, gdy wiadomość z żądaniem jest żądaniem 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, umożliwiając serwerowi WWW z interfejsem API egzekwowanie jednego zestawu zasad dla żądań GET i drugiego zestawu zasad dla żądań POST.

Pełne informacje znajdziesz w tych materiałach:

Przykład 1

Ten przykład pokazuje pojedynczy przepływ warunkowy o nazwie Convert-for-devices skonfigurowany w przepływie odpowiedzi ProxyEndpoint. Dodaj warunek jako element do elementu do którego ma zastosowanie dany warunek. W tym przykładzie warunek jest komponentem przepływu. Dlatego przepływ będzie wykonywany za każdym razem, gdy instrukcja zwróci wartość prawda.

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

Dla każdego żądania otrzymanego z aplikacji Edge przechowuje wartości wszystkich nagłówków HTTP obecnych jako zmiennych. Jeśli żądanie zawiera nagłówek HTTP o nazwie User-Agent, nagłówek ten oraz jego wartość jest przechowywana jako zmienna o nazwie request.header.User-Agent.

Biorąc pod uwagę powyższą konfigurację ProxyEndpoint, Edge sprawdza wartość request.header.User-Agent, aby sprawdzić, czy warunek przyjmuje wartość true (prawda).

Jeśli warunek jest spełniony, czyli wartość zmiennej request.header.User-Agent jest równa Mozilla, przepływ danych oparty na warunkach jest wykonywany, a zasady XMLtoJSON o nazwie ConvertToJSON są stosowane. Jeśli nie, przepływ nie jest wykonywany, a odpowiedź XML jest zwracana w niezmodyfikowanej formie (w formacie XML) do aplikacji przesyłającej żądanie.

Przykład 2

Rozważmy konkretny przykład, w którym musisz przekształcić komunikat odpowiedzi z formatu XML na format JSON – ale tylko na urządzeniach mobilnych. Najpierw utwórz zasadę, która przekształci Odpowiedź w formacie XML z interfejsu Weather API do JSON:

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

Konfiguracja zasad podawana powyżej instruuje serwer proxy interfejsu API, aby pobierał wiadomość z odpowiedzi, przeprowadzał konwersję z formatu XML na format JSON przy użyciu ustawień domyślnych, a następnie zapisywał wynik w nowej wiadomości z odpowiedzi. Jeśli konwertujesz wiadomość żądanie z XML-a na JSON, ustaw oba parametry te wartości do request).

.

Ponieważ chcesz przekształcić odpowiedzi z formatu XML na JSON, musisz skonfigurować przepływ odpowiedzi warunkowych, aby przeprowadzić konwersję. Aby na przykład przekonwertować wszystkie odpowiedzi z formatu XML na format 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łujesz interfejs API za pomocą żądania standardowego, odpowiedź jest sformatowana w formacie JSON.

Jednak Twoim celem jest konwertowanie raportów pogodowych tylko na format JSON, gdy klient, który wysłał żądanie, jest urządzeniem mobilnym. Aby włączyć takie dynamiczne działanie, musisz dodać do przepływu instrukcję warunkową.

Testowanie warunku warunkowego przepływ

W tej przykładowej prośbie nagłówek HTTP User-Agent ma wartość Mozilla, co powoduje, że instrukcja warunkowa zwraca wartość true, a przepływ warunkowy Convert-for-devices jest wykonywany.

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

lub pisać ładnie tam, gdzie 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 otrzymanie 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 do wzorca

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

Operatory

W tej sekcji opisujemy, jak korzystać z operatorów dopasowania do wzorca w wyrażeniach warunkowych wyciągi:

Dopasowania

Spójrzmy na kartę „Dopasowania” lub „~” z operatorem warunkowym. Te 2 operatory są takie same – angielska wersja „Matches” jest uważana za bardziej czytelną.

Podsumowanie: operator „Zgodność” 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 pasuje do zero lub więcej znaków. Zobaczmy, jak to działa.

Poniższy kod XML zawiera warunek kroku. Wykonuje zasadę somePolicy, gdy warunek zwraca wartość prawda. W tym przykładzie testujemy zmienną proxy.pathsuffix, która jest zmienną wbudowaną w Edge przechowującą sufiks ścieżki żądania. Pamiętaj, że możesz przetestować wartość dowolnej zmiennej przepływu zawierającej ciąg znaków. W tym przypadku, jeśli podstawowa ścieżka przychodzącego żądania to /animals, a żądanie to /animals/cat, to sufiks ścieżki to dosłowny 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 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 serwera proxy jest identyczny z „/cat”. Nie zostanie ona wykonana, jeśli sufiks to /bat lub /dog lub „/” lub cokolwiek innego.

Teraz rozważ to zdanie warunkowe, w którym 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 wdrażana? Tak, ponieważ symbol wieloznaczny pasuje do dowolnego znaku, "/cat′′ pasuje.

Wywołanie interfejsu API:

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

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

Wywołanie interfejsu API:

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

Czy zasada jest wdrażana? Oczywiście nie. Chociaż symbol wieloznaczny pasuje do „o”, litery „wl” nie są zgodne.

Przenieśmy teraz 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 pasuje do 0 lub większej liczby znaków.

Wywołanie interfejsu API:

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

Czy zasada jest wdrażana? Nie, „/bat” nie pasuje.

Wywołanie interfejsu API:

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

Czy zasada jest wdrażana? Tak, symbol wieloznaczny odpowiada zero lub więcej dowolnych znaków, dlatego „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 pasuje do dowolnych znaków, więc „/bird/mouse” powoduje dopasowanie. Zastanów się, jak za pomocą tego wyrażenia wciągniesz problem, ponieważ pasuje do wszystkiego po dosłownych znakach!

Pytanie: czy w przypadku operatora Dopasowanie wielkość liter ma znaczenie?

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 dowolnej litery (niezależnie od wielkości liter), ale mała litera „a” nie pasuje do „A”.

Wywołanie interfejsu API:

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

Czy zasada jest wdrażana? Tak, wielkość liter jest taka sama.

Pytanie: jak mogę stosować znaki ucieczki w operatorze dopasowania?

Użyj znaku procentowego „%”, aby zmienić znaczenie zarezerwowanych znaków. 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 Dopasowania szuka ciągu literału „c*at”.

Wywołanie interfejsu API:

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

Pytanie:Czy zasady są wdrażane?

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

JavaRegex

Jak widać, pole „Dopasowania” jest bardzo przydatne w prostych sytuacjach. Możesz też użyć innego „JavaRegex” lub „~~” . Oba te operatory są takie same, z tym że JavaRegex jest uznawany za bardziej czytelny. Nazwa JavaRegex pochodzi od tego, że pozwala ona na dopasowywanie wzorów wyrażeń regularnych. Edge stosuje te same reguły co klasy w pakiecie java.util.regex w języku Java. Sposób działania operatora JavaRegex znacznie się różni od Pasuje do operatora, dlatego nie należy ich mylić.

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

Ten kod przedstawia warunek kroku. Jeśli warunek jest prawdziwy, wykonuje zasadę SomePolicy. W tym przykładzie testujemy zmienną proxy.pathsuffix, która jest wbudowaną zmienną w Edge przechowującą sufiks ścieżki żądania. Jeśli ścieżka podstawowa argumentu żądanie przychodzące ma wartość /animals, a żądanie /animals/cat, sufiks ścieżki to ciąg literału „/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 SomePolicy? Podobnie jak w przypadku operatora Dopasowanie, w tym przypadku jest tylko jedna możliwość.

Wywołanie interfejsu API:

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

Czy zasada jest wdrażana? Tak, ponieważ sufiks ścieżki serwera proxy pasuje do „/cat” dokładnie. Nie uruchomi się, jeśli sufiks to /bat, /dog lub cokolwiek .

Utwórz wyrażenie regularne zawierające symbol „*” kwantyfikator. Ten operator ilościowy dopasowuje zero lub więcej wystąpień poprzedzającego 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! Symbol „*” kwantyfikator pasuje do zero lub większej liczby poprzedni znak, który jest „c”.

Wywołanie interfejsu API:

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

Czy zasada jest wdrażana? Tak, ponieważ symbol wieloznaczny pasuje do 0 lub większej liczby poprzednich znaku.

Następnie używamy kolumny „?” kwantyfikator, który pasuje do poprzedniego znaku raz lub nie .

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

Wywołanie interfejsu API:

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

Czy zasada jest wdrażana? Tak. Zmienna „?” odpowiada 0 lub 1 poprzedzającemu znakowi, który jest „a”.

Wywołanie interfejsu API:

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

Czy zasada jest wdrażana? Tak. Zmienna „?” odpowiada jednemu lub żadnemu poprzedzającemu znakowi. W tym przypadku nie ma słowa „a” tak więc makro zwraca wartość prawda.

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Nie. Symbol „?” kwantyfikator pasuje do jednego z poprzednich który jest znakiem „a”.

Następnie używamy stylu wyrażenia regularnego „[abc]” lub „grouping”. Dopasowuje znaki „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 „[cbr]” pasuje do „c”, „b” lub „r”. Te połączenia są również dopasowane:

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

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

Nie pasuje:

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

Pytanie: czy operator JavaRegex rozróżnia wielkość liter?

Tak. Załóżmy, że Twój warunek jest taki:

<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 pasuje do 0 lub 1 poprzedniego znaku, którym jest „a”.

Wywołanie interfejsu API:

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

Pytanie: Czy zasada jest wdrażana?

Nie, ponieważ wielka litera „A” nie jest zgodna z małą literą „a”.

MatchesPath

Operator MatchesPath możesz też określić w ten sposób: „~/”. Wygląda trochę jak Matches (~) i operatory JavaRegex (~~). Funkcja MatchesPath działa jednak zupełnie inaczej.

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

Operator MatchesPath umożliwia użycie dwóch rodzajów symboli wieloznacznych: pojedynczej gwiazdki (*) i podwójnej gwiazdki (**). Pojedyncza gwiazdka pasuje do jednego elementu ścieżki. Podwójna gwiazdka pasuje do: jeden lub wiele elementów ścieżki.

Przeanalizujmy poniższy przykład. W tym przykładzie testujemy zmienną proxy.pathsuffix, zmienną wbudowaną w Edge, która przechowuje sufiks ścieżki żądania. Pamiętaj jednak, że możesz testować 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 SomePolicy?

Wywołanie interfejsu API:

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

Pytanie: Czy zasada jest wdrażana?

Nie, ponieważ warunek wymaga kolejnego elementu ścieżki po „/animals”, zgodnie z wartością podaną przez „/*”.

Wywołanie interfejsu API:

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

Czy zasada jest wdrażana? 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ą stosowane?

Nie, ponieważ pojedyncza gwiazdka pasuje tylko do jednego elementu ścieżki, ten interfejs API zawiera więcej niż 1 element po „/animals”.

Teraz użyjemy podwójnego gwiazdki:

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

Wywołanie interfejsu API:

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

Czy zasada jest wdrażana? Nie, ponieważ warunek wymaga co najmniej 1 elementu ścieżki określonego za pomocą parametru „/**”.

Wywołanie interfejsu API:

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

Czy zasady są wdrażane?

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ą wdrażane?

Tak, ponieważ ścieżka zawiera co najmniej jeden element występujący za nim „/animals

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana?

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

Łączenie gwiazdek

Możesz użyć kombinacji gwiazdek pojedynczej (*) i podwójnej (**) w celu dalszego doprecyzowania dopasowania ścieżki.

    <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 będą pasować:

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

i

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



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

Zasoby interfejsu API

Usługi REST to zbiory zasobów interfejsu API. Zasób interfejsu API jest ścieżką identyfikatora URI fragment określający jednostkę, do której programiści mogą uzyskać dostęp za pomocą wywołania interfejsu API. Jeśli na przykład Twoja usługa dostarcza raportów i prognoz pogody, usługa backendowa może zdefiniować 2 zasoby interfejsu API:

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

Podczas tworzenia serwera proxy interfejsu API (jak pokazano w artykule Tworzenie pierwszego serwera proxy interfejsu API) musisz co najmniej utworzyć alias adresu URL podstawowego, który odwołuje się do usługi backendowej. Na przykład:

Podstawowy adres URL backendu Nowy/odpowiednik URL serwera proxy API
http://mygreatweatherforecast.com http://{your_org}-{environment}.apigee.net/mygreatweatherforecast

Na tym etapie możesz wykonywać wywołania interfejsu API w backendzie przy użyciu dowolnego podstawowego adresu URL. Gdy jednak użyjesz adresu URL proxy interfejsu API, sprawy zaczynają się komplikować.

Oprócz informacji o interfejsie 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 zapleczu. Zasadniczo oznacza to: „Jeśli do zasobu /reports przychodzi wywołanie GET, Edge powinien coś zrobić”.

Na ilustracji widać różnicę w zachowaniu 2 adresów URL, które ostatecznie uzyskują dostęp do tego samego backendu. Pierwszy to adres URL zasobu bez serwera proxy, a drugi to serwer proxy interfejsu Edge API z przepływem warunkowym do tego samego zasobu backendu. Poniżej opiszemy bardziej szczegółowo przepływy warunkowe.

Jak serwery proxy interfejsu API mapują się na konkretne zasoby backendu

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

Załóżmy, że chcesz, by Edge „zrobił coś” przy połączeniach przychodzących na /reports lub /forecasts zasobu. W tym momencie nie informujesz Edge co zrobić. Po prostu nasłuchuj połączeń do tych zasobów. Zrób to warunki. W serwisie Edge API proxy możesz tworzyć przepływy warunkowe dotyczące interfejsów /reports/forecasts. Do celów koncepcyjnych poniższy interfejs API kod XML serwera proxy 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>

Te warunki mówią: „Gdy żądanie GET zawiera /reports i /forecasts w adresie URL, Edge wykona wszystko, co Ty (jako deweloper interfejsu API) mu każesz, zgodnie z zasadami dołączonymi do tych przepływów.

Oto przykład ustawienia, co ma się stać, gdy spełni się warunek. W tym pliku XML proxy interfejsu API, gdy żądanie GET zostanie wysłane do adresu https://yourorg-test.apigee.net/mygreatweatherforecast/reports, Edge wykona 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 interfejs API ma też 2 domyślne przepływy: <PreFlow>, który jest wykonywany przed przepływami warunkowymi, oraz <PostFlow>, który jest wykonywany po nich. Są one przydatne do wykonywania zasad, gdy dowolne wywołanie zostanie wysłane do serwera proxy interfejsu API. Jeśli na przykład chcesz weryfikować klucz interfejsu API aplikacji przy każdym wywołaniu, niezależnie od zasobów backendu, do których uzyskujesz dostęp, możesz umieścić w <PreFlow> politykę weryfikacji klucza interfejsu API. Więcej informacji o przepływach znajdziesz w artykule Konfigurowanie przepływów.

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

Definiowanie ścieżek warunkowych do zasobów backendu w serwerze proxy interfejsu API jest całkowicie opcjonalne. Takie procesy warunkowe dają jednak możliwość szczegółowego zarządzania i monitorowania.

Dzięki niemu:

  • Stosuj zarządzanie w sposób, który odzwierciedla semantykę modelu interfejsu API.
  • Stosowanie zasad i zachowania skryptu do poszczególnych ścieżek zasobów (identyfikatorów URI)
  • Zbieranie szczegółowych danych na potrzeby usług Analytics

Załóżmy na przykład, że musisz zastosować różne typy logiki do zasobów backendowych /developers i /apps.

Aby to zrobić, dodaj 2 przepływy warunkowe na serwerze proxy API: /developers oraz /apps

W widoku rozwijania w panelu Nawigator edytora proxy interfejsu API kliknij ikonę + obok opcji domyślnej w sekcji Punkty końcowe proxy.

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

  • Nazwa procesu: deweloperzy
  • Typ warunku: ścieżka
  • Ścieżka: /developers

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

Teraz dodaj przepływ warunkowy dla /apps i załóżmy, że chcesz, aby warunek był wywoływany identyfikator URI i czasownik POST w żądaniu. Konfiguracja obejmuje ustawienie :

  • Nazwa przepływu: aplikacje
  • Typ warunku: Ścieżka i Czasownik
  • Ścieżka: /apps
  • Czynność: POST

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

W panelu Nawigator zobaczysz nowe przepływy dla aplikacji i Deweloperzy.

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

<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 przychodzącego żądania. (Zmienna proxy.pathsuffix wskazuje identyfikator URI żądania, które następuje po ścieżce BasePath skonfigurowanej w konfiguracji ProxyEndpoint).

Każdy zdefiniowany zasób API jest zaimplementowany przez przepływ warunkowy na serwerze proxy API. (Zobacz Konfigurowanie przepływów).

Po wdrożeniu proxy interfejsu API w środowisku testowym ta prośba:

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

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

Podany poniżej przykładowy warunek używa wyrażenia regularnego w Javie, aby rozpoznawać wywołania 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 Jak dopasować niezależnie ... w Społeczności Apigee.

Modelowanie hierarchicznych identyfikatorów URI

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

/developers/{developer_email}/apps

Możesz mieć zasoby, w których dla każdego elementu w kolekcji generowany jest unikalny identyfikator, który czasami jest oznaczany w ten sposób:

/genus/:id/species

Ta ścieżka dotyczy w równym stopniu tych dwóch 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

rozwiązuje te hierarchiczne adresy URI jako odpowiednie zasoby interfejsu API.

W niektórych przypadkach zwłaszcza w przypadku bardzo hierarchicznych interfejsów API, najlepiej będzie po prostu rozwiązywać wszystkie problemy, które są danego fragmentu identyfikatora URI. Aby to zrobić, w definicji zasobu użyj symbolu wieloznacznego z podwójną gwiazdką. Dla: możesz na przykład zdefiniować następujący zasób interfejsu API:
/developers/**

Ten zasób interfejsu API rozpozna następujące ścieżki identyfikatora URI:

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

Oto jak wygląda warunek przepływu warunkowego w definicji zastępnika interfejsu API:

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

Więcej przykładów

Warunek dołączony do reguły routingu

<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

Przykład praktyczny: zignoruj „/” na końcu ścieżki

Deweloperzy Edge zazwyczaj 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 mieć możliwość obsługi tego w wypowiedzeniach warunkowych. Ten konkretny przypadek użycia był omawiany w społeczności Apigee.

Jeśli wolisz, możesz to zrobić bez użycia wyrażenia regularnego:

    <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 zrozumiałe i czytelne.

Możesz jednak zrobić to samo za pomocą wyrażenia regularnego: Pętli nie trzeba jednak stosować.

<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 wdrażana? Tak. Pamiętaj, że w wyrażeniu regularnym znak „?” oznacza: dopasowanie do 0 lub 1 poprzedniego znaku. Dlatego zarówno „/cat”, jak i „/cat/” są dopasowaniami.

Wywołanie interfejsu API:

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

Czy zasada jest wdrażana? Nie. Wyrażenie regularne pasuje do 0 lub 1 poprzedniego znaku i nic więcej.

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

We wszystkich przykładach w tym temacie pokazujemy, jak dopasowywać jedną z wbudowanych zmiennych przepływu: proxy.pathsuffix. Warto wiedzieć, że możesz dopasowywać wzorce do dowolnego ciągu znaków lub zmiennej przepływu, niezależnie od tego, czy jest to wbudowana zmienna przepływu, taka jak proxy.pathsuffix.

Jeśli na przykład masz warunek, który testuje dowolny ciąg znaków, np. zwracany przez backend lub przez serwer uwierzytelniania, możesz użyć operatorów dopasowywania, aby przetestować ten ciąg znaków. Jeśli używasz JavaRegex, wyrażenie regularne zostanie porównane z całym ciągiem znaków w temacie. Jeśli temat to „abc”, a wyrażenie regularne to „[a-z]”, nie ma dopasowania, ponieważ wyrażenie „[a-z]” pasuje dokładnie do jednego znaku alfabetycznego. Wyrażenie „[a-z]+” działa tak samo jak „[a-z]*” i „[a-z]{3}”.

Przyjrzyjmy się konkretnemu przykładowi. Załóżmy, że serwer uwierzytelniania zwraca listę ról jako ciąg rozdzielony przecinkami: „editor, author, guest”.

Aby przetestować obecność roli edytującego, ta konstrukcja nie zadziała, ponieważ „Edytujący” to tylko część całego ciągu.

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

Natomiast ta konstrukcja zadziała:

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

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

W tym przykładzie możesz też sprawdzić, czy występuje słowo „editor” za pomocą operatora Dopasowanie:

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

Jednak w przypadkach, gdy potrzebujesz większej dokładności, JavaRegex jest często lepszym wyborem.

Umieszczanie cudzysłowów w wyrażeniach JavaRegex

Składnia warunku wymaga, aby wyrażenie JavaRegex było otoczone cudzysłowami prostymi. Jeśli więc masz wyrażenie regularne zawierające cudzysłowy proste, musisz znaleźć inny sposób dopasowania. Odpowiedź to Unicode. Załóżmy na przykład, że przekazujesz nagłówek zawierający podwójny cudzysłów, jak w poniższym przykładzie:
 -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ójny cudzysłów:
request.header.Content-Type ~~ "(multipart\/related)(; *type="application\/xop\+xml\")"
Rozwiązaniem jest zastąpienie cudzysłowów podwójnych opartych na ASCII ich odpowiednikiem w systemie Unicode \u0022. Na przykład: podane poniżej wyrażenie jest prawidłowe i zwraca oczekiwany wynik:
request.header.Content-Type ~~ "(multipart\/related)(; *type=\u0022application\/xop\+xml\u0022)"