Warunki ze zmiennymi przepływu

Przeglądasz dokumentację Apigee Edge.
Otwórz dokumentację Apigee X.
Informacje

Instrukcje warunkowe to wspólna struktura kontrolna we wszystkich językach programowania. Podobnie jak w języku programowania, konfiguracja serwera proxy interfejsu API obsługuje instrukcje warunkowe dla przepływów, zasad, kroków i reguł tras. Definiując instrukcje warunkowe, definiujesz zachowanie dynamiczne interfejsu API. To dynamiczne zachowanie pozwala na przykład na konwertowanie kodu XML na JSON tylko na potrzeby urządzeń mobilnych lub przekierowanie do adresu URL backendu na podstawie typu treści lub czasownika HTTP komunikatu żądania.

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

Skonfiguruj instrukcje warunkowe

Działanie warunkowe jest implementowane w serwerach proxy interfejsu API przy użyciu kombinacji conditions i conditions. Instrukcja warunkowa jest tworzona przy użyciu elementu Condition. Warunek jest pusty:

<Condition></Condition>

Aby utworzyć instrukcję warunkową, dodaj operator warunkowy i zmienną w celu utworzenia tej struktury:

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

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

Podczas pracy ze ścieżkami identyfikatorów URI możesz używać ~/ lub MatchesPath. Do wyrażenia regularnego JavaRegex możesz też używać operatora ~~.

Warunki są używane do definiowania warunkowych przepływów dla serwera proxy interfejsu API do zasobów interfejsu backendu API opisanego w sekcji Tworzenie przepływów warunkowych do zasobów interfejsu API backendu. Pełną listę warunków znajdziesz w dokumentacji warunków.

Zmienne

Warunki działają, bo oceniają wartości zmiennych. Zmienna to właściwość transakcji HTTP wykonywanej przez serwer proxy interfejsu API lub właściwość samej konfiguracji serwera proxy interfejsu API. Za każdym razem, gdy serwer proxy interfejsu API otrzyma żądanie z aplikacji, Apigee Edge wypełnia długą listę zmiennych związanych z czasem systemowym, informacjami o sieci aplikacji, nagłówkami HTTP w wiadomościach, konfiguracją serwera proxy interfejsu API, wykonaniami zasad itd. Spowoduje to utworzenie rozszerzonego kontekstu, którego możesz użyć do skonfigurowania instrukcji warunkowych.

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

Wyobraź sobie, że chcesz utworzyć instrukcję warunkową, która będzie egzekwować zasadę tylko wtedy, gdy komunikatem żądania jest GET. Aby utworzyć warunek oceniający czasownik HTTP żądania, utwórz instrukcję warunkową poniżej. Zmienna w tym warunku to request.verb. Wartość zmiennej to GET. Operatorem jest =.

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

Edge używa takiej instrukcji do oceny warunków. Powyższy przykład daje 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ść fałsz.

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

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

Aby np. utworzyć przepływ, który jest wykonywany tylko wtedy, gdy czasownik żądania jest typu GET:

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

Aby utworzyć jeden proces dla żądań GET i inny dla żądań POST:

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

Jak pokazano w przykładzie poniżej, możesz zastosować warunek do samego kroku dotyczącego zasad. Poniższy warunek powoduje, że zasadaVerifyApiKey jest egzekwowana tylko wtedy, gdy wiadomość żądania jest metodą 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, co pozwoli serwerowi proxy interfejsu API egzekwować jeden zestaw zasad dla żądań GET i inny zestaw zasad dla żądań POST.

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

Przykład 1

Poniższy przykład przedstawia pojedynczy przepływ warunkowy o nazwie Convert-for-devices skonfigurowany w przepływie odpowiedzi ProxyEndpoint. Dodaj warunek jako element do jednostki, której ten warunek ma zastosowanie. W tym przykładzie warunek jest elementem procesu. Dlatego proces jest wykonywany za każdym razem, gdy instrukcja przyjmie wartość „true” (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 występujących 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.

Biorąc pod uwagę podaną powyżej konfigurację ProxyEndpoint, Edge sprawdza wartość zmiennej request.header.User-Agent, aby sprawdzić, czy warunek jest spełniony.

Jeśli warunek zwróci wartość prawda, czyli wartość zmiennej request.header.User-Agent równa się Mozilla, zostanie uruchomiony przepływ warunkowy, a egzekwowana jest zasada XMLtoJSON o nazwie ConvertToJSON. W przeciwnym razie przepływ nie jest wykonywany, a odpowiedź XML jest zwracana do aplikacji żądającej bez żadnych zmian (w formacie XML).

Przykład 2

Wykorzystajmy konkretny przykład, 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 konwertuje odpowiedź w formacie XML z interfejsu Weather API na format JSON:

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

Powyższa konfiguracja zasad informuje serwer proxy interfejsu API, aby przyjął wiadomość z odpowiedzią, dokonał konwersji z formatu XML na JSON z ustawieniami domyślnymi, a następnie zapisał wynik na nową wiadomość z odpowiedzią. (Jeśli konwertujesz wiadomość żądanie z formatu XML na JSON, po prostu ustaw obie te wartości na request).

Chcesz przekonwertować odpowiedzi z formatu XML na JSON, dlatego musisz skonfigurować przepływ odpowiedzi warunkowej, aby wykonać konwersję. Aby na przykład przekonwertować wszystkie odpowiedzi z formatu XML na JSON, zanim zostaną zwrócone do aplikacji klienckiej, skonfiguruj poniższy przepływ odpowiedzi ProxyEndpoint.

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

Po wywołaniu interfejsu API za pomocą standardowego żądania odpowiedź jest sformatowana w formacie JSON.

Jednak Twoim celem jest konwersja raportów pogodowych na format JSON tylko wtedy, gdy klientem wysyłającym żądanie jest urządzenie mobilne. Aby włączyć takie dynamiczne zachowanie, musisz dodać instrukcję warunkową do przepływu.

Przetestuj przepływ warunkowy

W tym przykładowym żądaniu nagłówek HTTP User-Agent jest ustawiony na Mozilla, przez co instrukcja warunkowa zwraca wartość prawda, a przepływ warunkowy Convert-for-devices zostaje wykonany.

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

lub, aby po prostu wydrukować ten tekst, gdzie jest dostępny 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 inną wartością niż Mozilla zwróci odpowiedź 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 opisaliśmy, jak używać dopasowania wzorców z warunkami w przepływie Apigee.

Operatory

W tej sekcji opisujemy, jak używać tych operatorów dopasowania do wzorca w instrukcjach warunkowych:

Odpowiada

Przyjrzyjmy się najpierw operatorowi warunkowemu „Dopasowania” lub „~”. Te 2 operatory są takie same – za bardziej czytelną opcję uważa się wersję angielską „match”.

Podsumowanie: operator „Dopasowania” daje dwie możliwości. Dopasuj ciąg do ciągu dosłownie lub użyj symbolu wieloznacznego, używając symbolu „*”. Jak można się spodziewać, symbol wieloznaczny pasuje do 0 lub większej liczby znaków. Zobaczmy, jak to działa.

Poniższy kod XML zawiera warunek kroku. Gdy warunek przyjmuje wartość true (prawda), uruchamia zasadę somePolicy. 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 przetestować wartość dowolnej zmiennej przepływu, która zawiera ciąg znaków. Tak więc w tym przypadku, jeśli ścieżka bazowa przychodzącego żądania to /animals, a żądanie to /animals/cat, sufiks ścieżki jest ciągiem literału „/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 Niektóre zasady? Istnieje 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 dokładnie pasuje do „/cat”. Nie zostanie wykonany, jeśli sufiks to /bat, /dog, „/” lub inny element.

Spójrzmy teraz na 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 znak "/cat jest dopasowaniem.

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Tak. Symbol wieloznaczny pasuje do dowolnego znaku, dlatego "/bat" jest dopasowaniem.

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Na pewno nie – chociaż symbol wieloznaczny pasuje do wartości „o”, litery „wl” nie zostaną dopasowane.

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 zero lub więcej dowolnych znaków.

Wywołanie interfejsu API:

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

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

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Tak, symbol wieloznaczny pasuje do 0 lub większej liczby znaków, dlatego „123” tworzy 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 0 lub większej liczby znaków, więc „/bird/mouse” tworzy dopasowanie. Zastanów się, jak takie wyrażenie może wpaść w kłopoty, ponieważ pasuje do wszystkiego, co znajduje się po literału.

Pytanie: Czy w operatorze Dopasowania 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łe litery „a” nie pasują do litery „A”.

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Tak, przypadek jest zgodny.

Pytanie: Jak zmienić znaczenie znaków przy użyciu operatora „Dopasowanie”?

Aby zmienić znaczenie znaków zarezerwowanych, użyj znaku procentu „%”. 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ą przestrzegane?

Tak, ta ścieżka, choć nieco nietypowa, pasuje do wyników.

JavaRegex

Jak widać, operator „Dopasowania” doskonale sprawdza się w prostych sytuacjach. Możesz jednak użyć innego operatora – operatora „JavaRegex” lub „~~”. Są to te same operatory, z tą różnicą, że język JavaRegex jest uważany za bardziej czytelny. Nazywa się JavaRegex, ponieważ umożliwia dopasowywanie wzorców wyrażeń regularnych. Edge postępuje zgodnie z tymi samymi regułami co w klasach w pakiecie java.util.regex w języku Java. Sposób działania operatora JavaRegex bardzo się różni od operatora dopasowania, dlatego ważne jest, by nie mylić obu.

Podsumowanie: operator „JavaRegex” pozwala używać składni wyrażeń regularnych w instrukcjach warunkowych.

Poniższy kod przedstawia warunek kroku. Jeśli warunek przyjmuje wartość true (prawda), uruchamia zasadę somePolicy. W tym przykładzie testujemy zmienną proxy.pathsuffix, czyli wbudowaną zmienną w Edge, która przechowuje sufiks ścieżki żądania. Jeśli ścieżka bazowa przychodzącego żądania to /animals, a żądanie to /animals/cat, sufiks ścieżki jest ciągiem 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 zasady Niektóre zasady? Tak jak w przypadku operatora „match”, w tym przypadku istnieje 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 dokładnie pasuje do „/cat”. Nie zostanie wykonany, jeśli sufiks to /bat, /dog lub inny element.

Utwórzmy teraz wyrażenie regularne z użyciem kwantyfikatora „*”. Ten kwantyfikator pasuje do 0 lub większej liczby 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 „*” odpowiada zero lub większej liczbie poprzedniego znaku, czyli „c”.

Wywołanie interfejsu API:

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

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

Następnie używamy kwantyfikatora „?”, który pasuje do poprzedniego znaku jeden 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 „?” odpowiada zero lub 1 wystąpieniu poprzedniego znaku, czyli „a”.

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Tak. Kwantyfikator „?” pasuje do 1 z poprzednich znaków lub do żadnego z poprzednich znaków. W tym przypadku nie ma znaku „a”, więc warunek przyjmuje wartość prawda.

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Nie. Kwantyfikator „?” pasuje do jednego z poprzednich znaków, czyli „a”.

Następnie używamy stylu „[abc]” lub „grupowania” wyrażenia regularnego. Pasuje do znaków „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 tutaj wyrażeń regularnych, a wyrażenie „[cbr]” pasuje do „c”, „b” LUB „r”. Te połączenia są również dopasowane do:

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

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

Ale to nie pasuje:

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

Pytanie: czy w operatorze JavaRegex wielkość liter ma znaczenie?

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 odpowiada zero lub jednemu z poprzednich znaków, czyli „a”.

Wywołanie interfejsu API:

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

Pytanie: Czy zasady są przestrzegane?

Nie. Wielka litera „A” nie pasuje do małej litery „a”.

MatchesPath

Operator MatchesPath można też określić w ten sposób: „~/”. Wygląda on podobnie do operatorów Matches (~) i JavaRegex (~~). Ale MatchPath jest zupełnie inna.

Pamiętaj tylko, że ten operator analizuje ścieżkę jako serię elementów. Dlatego, jeśli ścieżka ma postać /animals/cats/wild, załóżmy, że składa się ona z części „/animals”, „/cats” i „/wild”.

Operator MatchesPath umożliwia korzystanie z 2 notacji z symbolami wieloznacznymi: pojedynczej gwiazdki (*) i podwójnej gwiazdki (**). Pojedyncza gwiazdka pasuje do 1 elementu ścieżki. Podwójna gwiazdka pasuje do co najmniej 1 elementu ścieżki.

Posłużmy się przykładem. W tym przykładzie testujemy zmienną proxy.pathsuffix, czyli wbudowaną zmienną w Edge, która przechowuje sufiks ścieżki żądania. Pamiętaj jednak, że możesz 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 Niektóre zasady?

Wywołanie interfejsu API:

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

Pytanie: Czy zasady są przestrzegane?

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

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Tak. Ścieżka ma inny element ścieżki (część po „/animals/”), ale jest po prostu pusta.

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Tak, ponieważ ścieżka wyraźnie zawiera element („/cats”), który znajduje się po elemencie „/animals

Wywołanie interfejsu API:

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

Pytanie: Czy zasady są przestrzegane?

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

Zastosujmy teraz podwójną gwiazdkę:

    <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 Niektóre zasady?

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Nie, ponieważ warunek wymaga co najmniej 1 poniższego elementu ścieżki, który jest określony przez parametr „/**”.

Wywołanie interfejsu API:

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

Czy zasady są respektowane?

Tak. Ścieżka ma inny element ścieżki (część po „/animals/”), ale jest po prostu pusta.

Wywołanie interfejsu API:

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

Czy zasady są respektowane?

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

Wywołanie interfejsu API:

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

Czy zasady są respektowane?

Tak, ponieważ ścieżka ma więcej niż 1 element, który występuje po elemencie „/animals”.

Łączenie gwiazdek

Aby dodatkowo doprecyzować dopasowanie ścieżki, możesz użyć kombinacji gwiazdek (* i podwójnej) (**).

    <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 dostaną dopasowanie:

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

i

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

i

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 to fragment ścieżki identyfikatora URI identyfikujący encję, do której deweloperzy mogą uzyskać dostęp przez wywołanie interfejsu API. Jeśli na przykład Twoja usługa udostępnia prognozy pogody i prognozy pogody, usługa backendu może zdefiniować 2 zasoby interfejsu API:

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

Podczas tworzenia serwera proxy interfejsu API (jak pokazano w sekcji Tworzenie pierwszego serwera proxy interfejsu API) tworzysz co najmniej alias bazowy adresu URL mapowany na usługę backendu. Na przykład:

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

W tym momencie możesz wykonywać wywołania interfejsu API do backendu, korzystając z dowolnego z podstawowych adresów URL. Jednak gdy korzystasz z adresu URL serwera proxy interfejsu API, sprawy zaczynają się interesować.

Oprócz statystyk interfejsu API, które Edge zaczyna zbierać, gdy korzystasz z serwera proxy interfejsu API, serwery proxy umożliwiają też definiowanie przepływów warunkowych mapowanych na zasoby w Twoim backendzie. W skrócie: „Jeśli wywołanie GET do zasobu /reports trafi do zasobu /reports, Edge powinien coś zrobić”.

Poniższy przykład przedstawia różnicę w działaniu 2 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 warunkowym przepływem do tego samego zasobu backendu. Poniżej szczegółowo omówimy procesy warunkowe.

Jak serwery proxy interfejsów API są mapowane na określone zasoby backendu

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

Załóżmy, że chcesz, aby usługa Edge „wykonała jakąś czynność”, gdy wywołania przychodzące do zasobów /reports lub /forecasts. W tym momencie nie mówisz usłudze Edge, co ma zrobić, tylko że powinna nasłuchiwać wywołań tych zasobów. Możesz to zrobić z warunkami. W serwerze proxy Edge API możesz utworzyć przepływy warunkowe dla usług /reports i /forecasts. Do celów koncepcyjnych poniższy plik 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 brzmią tak: „Gdy żądanie GET zawiera w adresie URL żądanie /reports i /forecasts, Edge wykona w sposób, do którego zwrócisz się (deweloper interfejsu API), w ramach zasad dołączonych do tych przepływów.

Oto przykład informowania Edge, co ma zrobić, gdy warunek zostanie spełniony. W tym kodzie XML serwera proxy interfejsu API, gdy żądanie GET jest wysyłane do https://yourorg-test.apigee.net/mygreatweatherforecast/reports, Edge w odpowiedzi wykonuje 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> wykonywane przed przepływami warunkowymi i <PostFlow> po wykonaniu przepływów warunkowych. Pomagają one realizować zasady, gdy dowolne wywołanie serwera proxy interfejsu API jest wykonywane. Jeśli na przykład chcesz weryfikować klucz interfejsu API aplikacji przy każdym wywołaniu, niezależnie od używanego zasobu backendu, możesz umieścić zasadę weryfikacji klucza interfejsu API w <PreFlow>. Więcej informacji o przepływach znajdziesz w artykule o konfigurowaniu przepływów.

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

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

Dzięki niemu:

  • Zastosuj zarządzanie w sposób odzwierciedlający semantykę modelu API
  • Stosowanie zasad i działań skryptów do poszczególnych ścieżek zasobów (identyfikatorów URI)
  • Zbieranie szczegółowych wskaźników dotyczących usług Analytics

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

Aby to zrobić, dodaj 2 procesy warunkowe na serwerze proxy interfejsu API: /developers i /apps.

W panelu Nawigator edytora proxy interfejsu API w widoku Programowanie kliknij ikonę + obok wartości domyślnej w punkcie końcowym serwera proxy.

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

  • Nazwa przepływu: deweloperzy
  • Condition Type (Typ warunku: Ścieżka)
  • Ścieżka: /developers

Warunek zostanie aktywowany (a zasady zostaną wykonane), jeśli do serwera proxy zostanie wysłane wywołanie zawierające ciąg /developers na końcu identyfikatora URI.

Dodaj teraz przepływ warunkowy dla /apps i załóż, że chcesz, aby warunek był wywoływany w żądaniu zarówno w przypadku identyfikatora URI, jak i czasownika POST. Konfiguracja obejmuje ustawienie:

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

Warunek zostanie aktywowany (i zasady zostaną wykonane), jeśli do serwera proxy zostanie wysłane wywołanie zawierające ciąg /apps na końcu identyfikatora URI i czasownik POST.

W panelu nawigacji zobaczysz nowe procesy dla Aplikacje i Deweloperów.

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

<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 określa identyfikator URI żądania po ścieżce BasePath skonfigurowanej w konfiguracji ProxyEndpoint).

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

Gdy wdrożysz serwer proxy interfejsu API w środowisku testowym, otrzymasz to żądanie:

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

sprawi, że warunek zmieni się na prawda, a ten przepływ, wraz ze wszystkimi powiązanymi zasadami, zostanie wykonany.

Ten przykładowy warunek używa wyrażenia regularnego w Javie do rozpoznawania wywołań zasobu /apps z końcowym ukośnikiem lub bez niego (/apps lub /apps/**):

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

Więcej informacji o tym rodzaju warunku znajdziesz w artykule How to match Niezależnie ... w Społeczności Apigee.

Modelowanie hierarchicznych identyfikatorów URI

W niektórych przypadkach będą dostępne hierarchiczne zasoby interfejsu API. Na przykład interfejs Developer Services API umożliwia wyświetlanie listy wszystkich aplikacji należących do dewelopera. Ścieżka identyfikatora URI:

/developers/{developer_email}/apps

W niektórych zasobach mogą się znajdować zasoby, w których dla każdego elementu w kolekcji generowany jest unikalny identyfikator, który może być czasami opisany w następujący sposób:

/genus/:id/species

Ta ścieżka ma zastosowanie w równym stopniu do tych 2 identyfikatorów URI:

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

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

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

odpowiednio rozpozna te hierarchiczne identyfikatory URI jako zasoby interfejsu API.

W niektórych przypadkach, zwłaszcza w przypadku interfejsów API o głębi hierarchicznej, może zajść potrzeba rozpoznania wszystkich elementów znajdujących się poniżej określonego fragmentu identyfikatora URI. Aby to zrobić, w definicji zasobów użyj symbolu wieloznacznego z podwójną gwiazdką. Jeśli na przykład zdefiniujesz ten zasób interfejsu API:
/developers/**

Zasób interfejsu API obsługuje te ścieżki identyfikatorów URI:

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

Oto jak mógłby wyglądać warunek przepływu warunkowego 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 reguły trasy

<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

Programiści Edge zazwyczaj chcą obsługiwać oba te sufiksy ścieżki: „/cat” i „/cat/”. Dzieje się tak, ponieważ niektórzy użytkownicy i klienci mogą wywoływać Twój interfejs API z dodatkowym ukośnikiem na końcu ścieżki, a Ty musisz radzić sobie z tym w instrukcjach warunkowych. Ten przypadek użycia został omówiony w społeczności Apigee.

Jeśli chcesz, możesz to osiągnąć bez użycia wyrażenia regularnego w ten sposób:

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

To dobra opcja. który jest jasny i czytelny.

To samo możesz zrobić z wyrażeniami regularnymi w ten sposób. Nawiasy służą do grupowania części wyrażenia zawierającej wyrażenia regularne, 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 dopasowanie do 0 lub jednego z poprzednich znaków. Dlatego obie kolumny „/cat” i „/cat/” są zgodne.

Wywołanie interfejsu API:

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

Czy zasada jest wykonywana? Nie. Wyrażenie regularne pasuje do 0 wystąpień poprzedniego znaku lub jest zgodne tylko z jednym wystąpieniem. Nic więcej nie jest dozwolone.

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

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

Jeśli na przykład masz warunek do testowania dowolnego ciągu, np. ciągu zwróconego w ładunku backendu lub ciągu zwróconego w wyniku wyszukiwania na serwerze uwierzytelniania, do przetestowania możesz użyć operatorów dopasowania. Jeśli używasz języka JavaRegex, wyrażenie regularne będzie porównywane z całym ciągiem znaków tematu. Jeśli podmiot to „abc”, a wyrażenie regularne to „[a-z]”, nie ma dopasowania, ponieważ „[a-z]” pasuje dokładnie do jednego znaku alfa. Wyrażenie „[a-z]+” działa podobnie jak „[a-z]*” i „[a-z]{3}.

Spójrzmy na konkretny przykład. Załóżmy, że serwer uwierzytelniania zwraca listę ról w postaci ciągu rozdzielanego przecinkami: „edytujący, autor, gość”.

Ta konstrukcja nie zadziała, ponieważ rolę edytującego można przetestować, ponieważ „edytujący” jest tylko częścią całego ciągu.

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

Jednak taka konstrukcja będzie działać:

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

Mechanizm ten uwzględnia podziały słów i inne części ciągu znaków z prefiksem .* i sufiksem.

W tym przykładzie możesz też przeprowadzić test dla słowa „editor” przy użyciu operatora dopasowania:

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

Jeśli jednak potrzebujesz większej precyzji, lepszym rozwiązaniem jest JavaRegex.

Zmiana znaczenia podwójnego cudzysłowu w wyrażeniach JavaRegex

Składnia warunku wymaga, aby wyrażenie JavaRegex znajdowało się w cudzysłowie prostym. Jeśli więc masz wyrażenie regularne zawierające podwójne cudzysłowy, musisz znaleźć inny sposób ich dopasowania. Odpowiedzią jest Unicode. Załóżmy na przykład, że przekazujesz nagłówek zawierający podwójne cudzysłowy:
 -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łowy warunek”, ponieważ wyrażenie zawiera cudzysłowy:
request.header.Content-Type ~~ "(multipart\/related)(; *type="application\/xop\+xml\")"
Rozwiązaniem jest zastąpienie cudzysłowów podwójnych ASCII:
 -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łowy warunek”, ponieważ wyrażenie zawiera cudzysłowy:
request.header.Content-Type ~~ "(multipart\/related)(; *type="application\/xop\+xml\")"
Rozwiązaniem jest zastąpienie cudzysłowów podwójnych ASCII:
 -H 'content-type:multipart/related; type="application/xop+xml"'
Jeśli spróbujesz dopasować ten nagłówek w swoim warunku Unicode, \u0022 Na przykład poniższe wyrażenie jest prawidłowe i daje oczekiwany wynik:
request.header.Content-Type ~~ "(multipart\/related)(; *type=\u0022application\/xop\+xml\u0022)"