Kondisi dengan variabel flow

Halaman ini berlaku untuk Apigee dan Apigee hybrid.

Lihat dokumentasi Apigee Edge.

Pernyataan kondisional adalah struktur kontrol umum di semua bahasa pemrograman. Seperti bahasa pemrograman, konfigurasi proxy API mendukung pernyataan kondisional untuk Alur, Kebijakan, Langkah, dan RouteRules. Dengan menentukan pernyataan kondisional, Anda menentukan perilaku dinamis untuk API. Perilaku dinamis ini memungkinkan Anda melakukan hal-hal seperti mengonversi XML menjadi JSON hanya untuk perangkat seluler, atau merutekan ke URL backend berdasarkan jenis konten atau kata kerja HTTP dari pesan permintaan.

Topik ini menunjukkan cara menggunakan kondisi untuk menerapkan fitur pengelolaan API secara dinamis saat runtime, tanpa menulis kode apa pun.

Mengonfigurasi pernyataan bersyarat

Perilaku kondisional diterapkan di proxy API menggunakan kombinasi kondisi dan variabel. Pernyataan kondisional dibuat menggunakan elemen Kondisi. Berikut adalah kondisi kosong:

<Condition></Condition>

Untuk membuat pernyataan kondisional, tambahkan operator kondisional dan variabel menggunakan sintaksis berikut:

<Condition>VARIABLE_NAME OPERATOR "VALUE"</Condition>

Contoh:

<Condition>request.verb = "GET"</Condition>

Operator kondisional yang didukung mencakup = (sama dengan), != (tidak sama dengan), dan > (lebih besar dari). Untuk keterbacaan, Anda juga dapat menulis kondisional sebagai teks: equals, notequals, greaterthan.

Saat menggunakan jalur URI, Anda dapat menggunakan ~/ atau MatchesPath. Anda juga dapat mencocokkan ekspresi reguler JavaRegex dengan operator ~~.

Kondisi digunakan untuk menentukan alur kondisional proxy API ke resource API backend, yang dijelaskan dalam Membuat alur kondisional ke resource API backend. Untuk daftar lengkap kondisional, lihat Referensi kondisi.

Variabel

Kondisi melakukan tugasnya dengan mengevaluasi nilai variabel. Variabel adalah properti transaksi HTTP yang dijalankan oleh proxy API, atau properti konfigurasi proxy API itu sendiri. Setiap kali proxy API mendapatkan permintaan dari aplikasi, Apigee mengisi daftar panjang variabel yang terkait dengan hal-hal seperti waktu sistem, informasi jaringan aplikasi, header HTTP pada pesan, konfigurasi proxy API, eksekusi kebijakan, dan sebagainya. Tindakan ini akan membuat konteks yang kaya yang dapat Anda gunakan untuk menyiapkan pernyataan kondisional.

Variabel selalu menggunakan notasi bertitik. Misalnya, header HTTP pada pesan permintaan tersedia sebagai variabel yang disebut request.header.HEADER_NAME. Jadi, untuk mengevaluasi Content-type header, Anda dapat menggunakan variabel request.header.Content-type. Misalnya, request.header.Content-type = "application/json" menunjukkan bahwa jenis konten permintaan harus berupa JSON.

Bayangkan Anda perlu membuat pernyataan kondisional yang akan menyebabkan kebijakan diterapkan hanya jika pesan permintaan adalah GET. Untuk membuat kondisi yang mengevaluasi kata kerja HTTP permintaan, Anda membuat pernyataan bersyarat di bawah. Variabel dalam kondisi ini adalah request.verb. Nilai variabel adalah GET. Operatornya adalah =.

<Condition>request.verb = "GET"</Condition>

Anda juga dapat menggunakan:

<Condition>request.verb equals "GET"</Condition>

Apigee menggunakan pernyataan tersebut untuk mengevaluasi kondisi. Contoh di atas dievaluasi menjadi benar jika kata kerja HTTP yang terkait dengan permintaan adalah GET. Jika kata kerja HTTP yang terkait dengan permintaan adalah POST, pernyataan akan bernilai salah.

Untuk mengaktifkan perilaku dinamis, Anda dapat melampirkan Kondisi ke Alur, Langkah, dan RouteRules.

Saat melampirkan kondisi ke Flow, Anda akan membuat Flow bersyarat. Alur bersyarat hanya dieksekusi jika kondisi bernilai benar (true). Anda dapat melampirkan Kebijakan sebanyak yang Anda inginkan ke Flow kondisional. Flow bersyarat memungkinkan Anda membuat aturan pemrosesan yang sangat khusus untuk pesan permintaan atau respons yang memenuhi kriteria tertentu.

Misalnya, untuk membuat Flow yang hanya dieksekusi jika kata kerja permintaan adalah GET:

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

Untuk membuat satu Flow untuk permintaan GET dan satu lagi untuk permintaan POST:

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

Seperti yang ditunjukkan pada contoh di bawah, Anda dapat menerapkan kondisi ke Langkah Kebijakan itu sendiri. Kondisi berikut menyebabkan kebijakan VerifyAPIKey diterapkan hanya jika pesan permintaan adalah POST.

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

Setelah menentukan Alur bersyarat tersebut, Anda dapat melampirkan Kebijakan ke alur tersebut, sehingga proxy API dapat menerapkan satu kumpulan kebijakan untuk permintaan GET, dan kumpulan kebijakan lain untuk permintaan POST.

Untuk informasi referensi yang komprehensif, lihat referensi berikut:

Contoh 1

Contoh berikut menunjukkan satu alur bersyarat bernama Convert-for-devices, yang dikonfigurasi dalam alur respons ProxyEndpoint. Tambahkan Kondisi sebagai elemen ke entity tempat kondisi diterapkan. Dalam contoh ini, kondisi adalah komponen alur. Oleh karena itu, flow akan dieksekusi setiap kali pernyataan dievaluasi menjadi true.

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

Untuk setiap permintaan yang diterima dari aplikasi, Apigee menyimpan nilai semua header HTTP yang ada sebagai variabel. Jika permintaan berisi header HTTP yang disebut User-Agent, header tersebut dan nilainya akan disimpan sebagai variabel yang disebut request.header.User-Agent.

Dengan konfigurasi ProxyEndpoint di atas, Apigee akan memeriksa nilai variabel request.header.User-Agent untuk melihat apakah kondisinya bernilai benar.

Jika kondisi bernilai true, yaitu nilai variabel request.header.User-Agent sama dengan Mozilla, Flow kondisional akan dieksekusi dan kebijakan XMLtoJSON yang disebut ConvertToJSON akan diterapkan. Jika tidak, Flow tidak akan dieksekusi, dan respons XML akan ditampilkan tanpa diubah (dalam format XML) ke aplikasi yang meminta.

Contoh 2

Mari kita gunakan contoh spesifik saat Anda perlu mengubah pesan respons dari XML menjadi JSON—tetapi hanya untuk perangkat seluler. Pertama, buat kebijakan yang akan mengonversi respons berformat XML dari Weather API menjadi JSON:

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

Konfigurasi kebijakan di atas memberi tahu proxy API untuk mengambil pesan respons, melakukan konversi dari XML ke JSON dengan setelan default, lalu menulis hasilnya ke pesan respons baru. (Jika mengonversi pesan request dari XML ke JSON, Anda cukup menetapkan kedua nilai ini ke request.)

Karena Anda ingin mengonversi respons dari XML ke JSON, Anda perlu mengonfigurasi Flow respons bersyarat untuk melakukan konversi. Misalnya, untuk mengonversi semua respons dari XML ke JSON sebelum ditampilkan ke aplikasi klien, konfigurasikan Alur respons ProxyEndpoint berikut.

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

Saat Anda memanggil API menggunakan permintaan standar, respons akan diformat dalam JSON.

Namun, sasaran Anda adalah hanya mengonversi laporan Cuaca menjadi JSON jika klien yang meminta adalah perangkat seluler. Untuk mengaktifkan perilaku dinamis tersebut, Anda harus menambahkan pernyataan kondisional ke Flow.

Menguji alur kondisional

Dalam contoh permintaan ini, header User-Agent HTTP ditetapkan ke Mozilla, sehingga menyebabkan pernyataan bersyarat dievaluasi menjadi benar dan alur bersyarat Convert-for-devices dieksekusi.

curl -H "User-Agent:Mozilla" http://example.com/weather/forecastrss?w=12797282

atau, untuk mencetak dengan format yang baik jika Python tersedia:

curl -H "User-Agent:Mozilla" http://example.com/weather/forecastrss?w=12797282 | python -mjson.tool

Contoh Respons:

. . .

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

. . .

Permintaan yang dikirimkan tanpa header User-Agent, atau dengan nilai yang berbeda dari Mozilla, akan menghasilkan respons berformat XML.

$ curl http://example.com/weather/forecastrss?w=12797282

Respons XML yang tidak diubah akan ditampilkan.

Contoh Respons:

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

Pencocokan pola

Bagian ini menjelaskan cara menggunakan pencocokan pola dengan kondisi dalam alur Apigee.

Operator

Bagian ini menjelaskan cara menggunakan operator pencocokan pola berikut dalam pernyataan kondisional:

Mencocokkan dengan

Mari kita lihat operator kondisional Matches atau ~ terlebih dahulu. Kedua operator ini sama — versi bahasa Inggris, Matches, dianggap sebagai opsi yang lebih mudah dibaca.

Ringkasan: Operator Matches memberi Anda dua kemungkinan. Cocokkan string secara literal, atau lakukan pencocokan karakter pengganti dengan *. Seperti yang Anda duga, karakter pengganti cocok dengan nol karakter atau lebih. Mari kita lihat cara kerjanya.

XML berikut menunjukkan kondisi Langkah. Fungsi ini mengeksekusi kebijakan SomePolicy saat kondisi bernilai benar. Dalam contoh ini, kita menguji variabel proxy.pathsuffix, variabel bawaan di Apigee yang menyimpan akhiran jalur permintaan. Namun, perlu diperhatikan bahwa Anda dapat menguji nilai variabel flow yang berisi string. Jadi, dalam hal ini, jika jalur dasar permintaan masuk adalah /animals, dan permintaannya adalah /animals/cat, maka akhiran jalur adalah string literal /cat.

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

Pertanyaan: Akhiran jalur proxy apa yang akan menyebabkan SomePolicy dieksekusi? Hanya ada satu kemungkinan.

Panggilan API:

GET http://example.com/matchtest/cat

Apakah kebijakan dijalankan? Ya, karena akhiran jalur proxy sama persis dengan /cat. Fungsi ini tidak akan dieksekusi jika akhiran adalah /bat atau /dog atau / atau yang lainnya.

Sekarang, pertimbangkan pernyataan bersyarat ini saat kita menggunakan karakter pengganti *:

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

Panggilan API:

GET http://example.com/matchtest/cat

Apakah kebijakan dijalankan? Ya, karena karakter pengganti cocok dengan karakter apa pun, dan "/cat" cocok.

Panggilan API:

GET http://example.com/matchtest/bat

Apakah kebijakan dijalankan? Ya, karena karakter pengganti cocok dengan karakter apa pun, "/bat" cocok.

Panggilan API:

GET http://example.com/matchtest/owl

Apakah kebijakan dijalankan? Tentu saja tidak — meskipun karakter pengganti cocok dengan o, huruf wl tidak cocok.

Sekarang, mari kita pindahkan karakter pengganti ke akhir akhiran:

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

Panggilan API:

GET http://example.com/matchtest/cat

Apakah kebijakan dijalankan? Ya, karena karakter pengganti cocok dengan nol atau beberapa karakter apa pun.

Panggilan API:

GET http://example.com/matchtest/bat

Apakah kebijakan dijalankan? Tidak, /bat tidak cocok.

Panggilan API:

GET http://example.com/matchtest/cat123

Apakah kebijakan dijalankan? Ya, karakter pengganti cocok dengan nol atau beberapa karakter apa pun, sehingga 123 menghasilkan kecocokan.

Panggilan API:

GET http://example.com/matchtest/cat/bird/mouse

Apakah kebijakan dijalankan? Ya, karena karakter pengganti cocok dengan nol atau beberapa karakter apa pun, sehingga /bird/mouse menghasilkan kecocokan. Perhatikan bagaimana ekspresi seperti ini dapat membuat Anda mengalami masalah karena cocok dengan semua hal setelah karakter literal.

Pertanyaan: Apakah operator Matches peka huruf besar/kecil?

Ya. Misalkan Anda memiliki kondisi seperti ini:

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

Panggilan API:

GET http://example.com/matchtest/cat

Apakah kebijakan dijalankan? Tidak, karakter pengganti cocok dengan huruf apa pun (terlepas dari huruf besar/kecil), tetapi a huruf kecil tidak cocok dengan A.

Panggilan API:

GET http://example.com/matchtest/bAt

Apakah kebijakan dijalankan? Ya, kasusnya cocok.

Pertanyaan: Bagaimana cara meng-escape karakter dengan operator Matches?

Gunakan karakter persen % untuk meng-escape karakter khusus. Contoh:

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

Panggilan API:

GET http://example.com/matchtest/cat

Apakah kebijakan dijalankan? Tidak, operator Matches mencari string literal c*at.

Panggilan API:

GET http://example.com/matchtest/c*at

Pertanyaan:Apakah kebijakan tersebut dieksekusi?

Ya, jalur ini, meskipun sedikit tidak biasa, cocok.

JavaRegex

Seperti yang dapat Anda lihat, operator Matches sangat cocok untuk situasi sederhana. Namun, Anda dapat menggunakan operator lain, yaitu operator JavaRegex atau ~~. Keduanya adalah operator yang sama, kecuali JavaRegex dianggap lebih mudah dibaca. Class ini disebut JavaRegex karena memungkinkan pencocokan pola ekspresi reguler, dan Apigee mengikuti aturan yang sama dengan class dalam paket java.util.regex dalam bahasa Java. Cara kerja operator JavaRegex sangat berbeda dengan operator Matches, jadi jangan sampai Anda salah membedakan keduanya.

Ringkasan: Operator JavaRegex memungkinkan Anda menggunakan sintaksis ekspresi reguler dalam pernyataan kondisional.

Kode berikut menunjukkan kondisi Langkah. Fungsi ini mengeksekusi kebijakan SomePolicy jika kondisinya bernilai true. Dalam contoh ini, kita menguji variabel proxy.pathsuffix, variabel bawaan di Apigee yang menyimpan akhiran jalur permintaan. Jika jalur dasar permintaan masuk adalah /animals, dan permintaannya adalah /animals/cat, akhiran jalurnya adalah string literal /cat.

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

Pertanyaan: Akhiran jalur proxy apa yang akan menyebabkan SomePolicy dieksekusi? Sama seperti operator Matches, hanya ada satu kemungkinan dalam hal ini.

Panggilan API:

GET http://example.com/matchtest/cat

Apakah kebijakan dijalankan? Ya, karena akhiran jalur proxy sama persis dengan /cat. Fungsi ini tidak akan dieksekusi jika akhiran adalah /bat atau /dog atau yang lainnya.

Sekarang, mari kita buat ekspresi reguler menggunakan penghitung *. Kuantifier ini cocok dengan nol atau beberapa karakter sebelumnya.

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

Panggilan API:

GET http://example.com/matchtest/cat

Apakah kebijakan dijalankan? Tidak! Kuantifier * cocok dengan nol atau beberapa karakter sebelumnya, yang merupakan c.

Panggilan API:

GET http://example.com/matchtest/ccccct

Apakah kebijakan dijalankan? Ya, karena karakter pengganti cocok dengan nol atau beberapa karakter sebelumnya.

Selanjutnya, kita menggunakan penghitung ?, yang cocok dengan karakter sebelumnya satu kali, atau sama sekali tidak cocok.

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

Panggilan API:

GET http://example.com/matchtest/cat

Apakah kebijakan dijalankan? Ya. Penghitung ? cocok dengan nol atau satu kemunculan karakter sebelumnya, yang merupakan a.

Panggilan API:

GET http://example.com/matchtest/ct

Apakah kebijakan dijalankan? Ya. Kuantifier ? cocok dengan satu atau tidak satu pun karakter sebelumnya. Dalam hal ini, tidak ada karakter a, sehingga kondisi bernilai true.

Panggilan API:

GET http://example.com/matchtest/caat

Apakah kebijakan dijalankan? Tidak. Kuantifier ? cocok dengan satu karakter sebelumnya, yaitu a.

Selanjutnya, kita akan menggunakan gaya ekspresi regex [abc] atau pengelompokan. Pola ini cocok dengan karakter a atau b atau c.

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

Panggilan API:

GET http://example.com/matchtest/cat

Apakah kebijakan dijalankan? Ya. Di sini, kita menggunakan ekspresi reguler, dan ekspresi [cbr] cocok dengan c, b, ATAU r. Panggilan ini juga cocok:

GET http://example.com/matchtest/bat

GET http://example.com/matchtest/rat

Namun, ini bukan kecocokan:

GET http://example.com/matchtest/mat

Pertanyaan: Apakah operator JavaRegex peka huruf besar/kecil?

Ya. Misalkan Anda memiliki kondisi seperti ini:

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

Panggilan API:

GET http://example.com/matchtest/cat

Apakah kebijakan dijalankan? Ya, ekspresi reguler cocok dengan nol atau salah satu karakter sebelumnya, yaitu a.

Panggilan API:

GET http://example.com/matchtest/cAt

Pertanyaan: Apakah kebijakan tersebut dieksekusi?

Tidak, karena huruf besar A tidak cocok dengan huruf kecil a.

MatchesPath

Operator MatchesPath juga dapat ditentukan seperti ~/ ini. Operator ini terlihat sedikit seperti operator Matches (~) dan JavaRegex (~~). Namun, MatchesPath sepenuhnya berbeda.

Ingatlah bahwa operator ini melihat jalur sebagai serangkaian bagian. Oleh karena itu, jika jalurnya adalah: /animals/cats/wild, Anda dapat menganggap jalur tersebut terdiri dari bagian /animals, /cats, dan /wild.

Operator MatchesPath memungkinkan Anda menggunakan dua notasi karakter pengganti: satu tanda bintang (*) dan tanda bintang ganda (**). Tanda bintang tunggal cocok dengan satu elemen jalur. Tanda bintang ganda cocok dengan satu atau beberapa elemen jalur.

Mari perhatikan contoh berikut. Dalam contoh ini, kita menguji variabel proxy.pathsuffix, variabel bawaan di Apigee yang menyimpan akhiran jalur permintaan. Namun, perlu diperhatikan bahwa Anda dapat menguji nilai variabel flow apa pun yang berisi string.

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

Pertanyaan: Akhiran jalur proxy apa yang akan menyebabkan SomePolicy dieksekusi?

Panggilan API:

GET http://example.com/matchtest/animals

Pertanyaan: Apakah kebijakan tersebut dieksekusi?

Tidak, karena kondisi memerlukan elemen jalur lain setelah /animals, seperti yang ditentukan oleh /*.

Panggilan API:

GET http://example.com/matchtest/animals/

Apakah kebijakan dijalankan? Ya, jalur memang memiliki elemen jalur lain (bagian setelah /animals/), tetapi kosong.

Panggilan API:

GET http://example.com/matchtest/animals/cats

Apakah kebijakan dijalankan? Ya, karena jalur tersebut jelas memiliki elemen (/cats) yang muncul setelah /animals

Panggilan API:

GET http://example.com/matchtest/animals/cats/wild

Pertanyaan: Apakah kebijakan tersebut dieksekusi?

Tidak, karena satu tanda bintang hanya cocok dengan satu elemen jalur, dan API ini memiliki lebih dari satu elemen setelah /animals.

Sekarang mari kita gunakan tanda bintang ganda:

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

Pertanyaan: Akhiran jalur proxy apa yang akan menyebabkan SomePolicy dieksekusi?

Panggilan API:

GET http://example.com/matchtest/animals

Apakah kebijakan dijalankan? Tidak, karena kondisi memerlukan setidaknya satu elemen jalur berikut yang ditentukan oleh /**.

Panggilan API:

GET http://example.com/matchtest/animals/

Apakah kebijakan tersebut dijalankan?

Ya, jalur memang memiliki elemen jalur lain (bagian setelah /animals/), tetapi kosong.

Panggilan API:

GET http://example.com/matchtest/animals/cats

Apakah kebijakan tersebut dijalankan?

Ya, karena jalur memiliki setidaknya satu elemen yang muncul setelah /animals

Panggilan API:

GET http://example.com/matchtest/animals/cats/wild

Apakah kebijakan tersebut dijalankan?

Ya, karena jalur memiliki lebih dari satu elemen yang muncul setelah /animals

Mencampur tanda bintang

Anda dapat menggunakan kombinasi tanda bintang tunggal (*) dan ganda (**) untuk lebih menyaring pencocokan jalur.

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

Panggilan API:

Semua panggilan API ini akan menghasilkan kecocokan:

GET http://example.com/matchtest/animals/cats/wild/

dan

GET http://example.com/matchtest/animals/dogs/wild/austrailian

dan

GET http://example.com/matchtest/animals/birds/wild/american/finches

Resource API

Layanan RESTful adalah kumpulan resource API. Resource API adalah fragmen jalur URI yang mengidentifikasi beberapa entitas yang dapat diakses developer dengan memanggil API Anda. Misalnya, jika layanan Anda menyediakan laporan cuaca dan perkiraan cuaca, layanan backend Anda mungkin menentukan dua resource API:

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

Saat membuat proxy API (seperti yang ditunjukkan dalam Mem-build proxy API pertama Anda), setidaknya Anda membuat URL dasar alias yang dipetakan ke layanan backend Anda. Contoh:

URL dasar backend URL proxy API baru/setara
http://mygreatweatherforecast.com http://example.com/mygreatweatherforecast

Pada tahap ini, Anda dapat melakukan panggilan API ke backend menggunakan salah satu URL dasar. Namun, saat Anda menggunakan URL proxy API, hal-hal mulai menarik.

Selain analisis API yang mulai dikumpulkan Apigee saat Anda menggunakan proxy API, proxy juga memungkinkan Anda menentukan alur kondisional yang dipetakan ke resource di backend. Pada dasarnya, Jika panggilan GET masuk ke resource /reports, Apigee harus melakukan sesuatu.

Gambar berikut menunjukkan perbedaan perilaku antara dua URL yang pada akhirnya mengakses backend yang sama. Satu adalah URL resource tanpa proxy, yang lainnya adalah proxy Apigee API dengan alur kondisional ke resource backend yang sama. Kita akan menjelaskan alur kondisional secara lebih mendetail di bawah.

Untuk URL proxy Apigee API dengan alur kondisional, respons akan mengonversi XML menjadi JSON
    dan mengumpulkan analisis.

Cara proxy API dipetakan ke resource backend tertentu

Dengan URL proxy API yang dipetakan ke URL dasar layanan backend (saat Anda membuat proxy), Anda dapat menambahkan alur kondisional ke resource tertentu, seperti resource /reports dan /forecasts yang disebutkan sebelumnya.

Misalnya, Anda ingin Apigee melakukan sesuatu saat panggilan masuk ke resource /reports atau /forecasts. Pada tahap ini, Anda tidak memberi tahu Apigee apa yang harus dilakukan, hanya bahwa Apigee harus memproses panggilan ke resource tersebut. Anda melakukannya dengan kondisi. Di proxy API Apigee, Anda dapat membuat alur bersyarat untuk /reports dan /forecasts. Untuk tujuan konseptual, XML proxy API berikut menunjukkan tampilan kondisi tersebut.

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

Kondisi tersebut menyatakan, Saat permintaan GET masuk dengan /reports dan /forecasts di URL, Apigee akan melakukan apa pun yang Anda (developer API) perintahkan, melalui kebijakan yang Anda lampirkan ke alur tersebut.

Sekarang, berikut adalah contoh cara memberi tahu Apigee tindakan yang harus dilakukan saat kondisi terpenuhi. Dalam XML proxy API berikut, saat permintaan GET dikirim ke https://example.com/mygreatweatherforecast/reports, Apigee akan menjalankan kebijakan XML-to-JSON-1 dalam respons.

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

Selain alur kondisional opsional tersebut, setiap proxy API juga dilengkapi dengan dua alur default: <PreFlow> yang dieksekusi sebelum alur kondisional, dan <PostFlow> yang dieksekusi setelah alur kondisional. Fungsi ini berguna untuk menjalankan kebijakan saat panggilan apa pun dilakukan ke proxy API. Misalnya, jika ingin memverifikasi kunci API aplikasi dengan setiap panggilan, terlepas dari resource backend yang diakses, Anda dapat menerapkan kebijakan Verifikasi Kunci API di <PreFlow>. Untuk mengetahui informasi selengkapnya tentang alur, lihat Mengonfigurasi alur.

Membuat alur bersyarat ke resource backend

Menentukan alur kondisional ke resource backend di proxy API sepenuhnya bersifat opsional. Namun, alur kondisional tersebut memberi Anda kemampuan untuk menerapkan pengelolaan dan pemantauan terperinci.

Anda akan dapat:

  • Terapkan pengelolaan dengan cara yang mencerminkan semantik model API Anda
  • Menerapkan kebijakan dan perilaku dengan skrip ke setiap jalur resource (URI)
  • Mengumpulkan metrik terperinci untuk Layanan Analytics

Misalnya, bayangkan Anda perlu menerapkan berbagai jenis logika ke resource /developers hingga /apps backend.

Untuk melakukannya, Anda menambahkan dua alur kondisional di proxy API: /developers dan /apps.

Editor Proxy Baru

Untuk menambahkan alur kondisional:

  1. Pilih tab Develop di Proxy Editor.
  2. Pilih Endpoint proxy > default di panel kiri.

    Pilih Endpoint proxy > default di panel kiri.

  3. Klik tombol + di atas panel Respons.

    Tombol tambahkan alur kondisional

  4. Pada dialog Add Conditional Flow, masukkan konfigurasi berikut:
    • Nama alur: Developers
    • Condition Type: Path
    • Jalur: /developers

    Menambahkan dialog alur kondisional.

    Kondisi akan dipicu (dan kebijakan akan dijalankan) jika panggilan dikirim ke proxy dengan /developers di akhir URI.

  5. Sekarang, tambahkan alur kondisional untuk /apps, dan asumsikan Anda ingin kondisi dipicu pada URI dan kata kerja POST dalam permintaan. Konfigurasi ini melibatkan penetapan hal berikut:
    • Flow Name: Apps
    • Condition Type: Path and Verb
    • Jalur: /apps
    • Kata Kerja: POST

    Kondisi akan dipicu (dan kebijakan akan dijalankan) jika panggilan dikirim ke proxy dengan /apps di akhir URI dan kata kerja POST.

Alur yang ditambahkan akan ditampilkan di panel Response:

Menambahkan dialog alur kondisional.

Editor Proxy Klasik

Di panel Develop pada panel Navigator editor proxy API, klik di samping default di Proxy Endpoints.

Saat Anda mengarahkan kursor ke tanda plus di samping default, teks kursor akan bertuliskan Tambahkan
    Alur Baru.

Di jendela New Conditional Flow, masukkan konfigurasi kunci berikut:

  • Nama alur: Developers
  • Condition Type: Path
  • Jalur: /developers

Di panel Alur Bersyarat Baru, alur bernama Developer dikonfigurasi dengan
    deskripsi &quot;Developer aplikasi yang terdaftar dengan Layanan Developer&quot;.

Kondisi akan dipicu (dan kebijakan akan dijalankan) jika panggilan dikirim ke proxy dengan /developers di akhir URI.

Sekarang tambahkan alur kondisional untuk /apps, dan asumsikan Anda ingin kondisi dipicu pada URI dan kata kerja POST dalam permintaan. Konfigurasi ini melibatkan setelan berikut:

  • Flow Name: Apps
  • Condition Type: Path and Verb
  • Jalur: /apps
  • Kata Kerja: POST

Di panel Alur Bersyarat Baru, alur bernama Aplikasi dikonfigurasi dengan
    deskripsi &quot;Aplikasi developer yang terdaftar di Layanan Developer&quot;.

Kondisi akan dipicu (dan kebijakan akan dijalankan) jika panggilan dikirim ke proxy dengan /apps di akhir URI dan kata kerja POST.

Di panel Navigator, Anda akan melihat alur baru untuk Aplikasi dan Developer.

Alur baru untuk Aplikasi dan Developer ditampilkan di panel Navigator pada bagian Proxy Endpoints.

Pilih salah satu alur untuk melihat konfigurasi alur bersyarat di tampilan kode editor proxy 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>

Seperti yang dapat Anda lihat, resource API hanyalah Flow bersyarat yang mengevaluasi jalur URI dari permintaan masuk. (Variabel proxy.pathsuffix mengidentifikasi URI permintaan yang mengikuti BasePath yang dikonfigurasi dalam konfigurasi ProxyEndpoint.)

Setiap resource API yang Anda tentukan diterapkan oleh alur kondisional di proxy API. (Lihat Mengonfigurasi alur.)

Setelah Anda men-deploy proxy API ke lingkungan pengujian, permintaan berikut:

http://example.com/PROXY_PATH/apps

akan menyebabkan kondisi dievaluasi menjadi true, dan alur ini, beserta kebijakan terkait, akan dijalankan.

Contoh kondisi berikut menggunakan ekspresi reguler Java untuk mengenali panggilan yang dilakukan ke resource /apps dengan atau tanpa garis miring depan di akhir (/apps atau /apps/**):

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

Untuk mengetahui informasi selengkapnya tentang jenis kondisi ini, lihat Cara mencocokkan terlepas dari apakah ada "/" di akhir ... di Komunitas Apigee.

Membuat model URI hierarkis

Dalam beberapa kasus, Anda akan memiliki resource API hierarkis. Misalnya, API daftar aplikasi developer menyediakan metode untuk mencantumkan semua aplikasi milik developer. Jalur URI adalah:

/developers/DEVELOPER_EMAIL/apps

Anda mungkin memiliki resource yang menghasilkan ID unik untuk setiap entitas dalam koleksi, yang terkadang dianotasi sebagai berikut:

/genus/:id/species

Jalur ini berlaku sama untuk dua URI berikut:

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

Untuk merepresentasikan struktur ini dalam resource API, Anda dapat menggunakan karakter pengganti. Contoh:

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

Tindakan ini akan me-resolve URI hierarkis sebagai resource API dengan tepat.

Dalam beberapa kasus, terutama untuk API hierarkis yang mendalam, Anda mungkin hanya ingin me-resolve semuanya di bawah fragmen URI tertentu. Untuk melakukannya, gunakan karakter pengganti tanda bintang ganda dalam definisi resource Anda. Misalnya, jika Anda menentukan resource API berikut:

/developers/**

Resource API tersebut akan me-resolve jalur URI berikut:

/developers/DEVELOPER_EMAIL/apps
/developers/DEVELOPER_EMAIL/keys
/developers/DEVELOPER_EMAIL/apps/APP_ID/keys

Berikut adalah tampilan kondisi alur kondisional dalam definisi proxy API:

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

Contoh lainnya

Kondisi yang dilampirkan ke 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>

Kondisi yang dilampirkan ke kebijakan

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

Alur Bersyarat

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

Contoh operator dalam kondisi

Berikut beberapa contoh operator yang digunakan untuk membuat kondisi:

  • 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

Contoh praktis: Abaikan / di akhir jalur

Developer Apigee biasanya ingin menangani kedua akhiran jalur ini: /cat dan /cat/. Hal ini karena beberapa pengguna atau klien mungkin memanggil API Anda dengan garis miring tambahan di akhir jalur, dan Anda harus dapat menanganinya dalam pernyataan kondisional. Kasus penggunaan yang tepat ini telah dibahas dalam cara mencocokkan terlepas dari apakah ada '/' di akhir URL....

Jika mau, Anda dapat melakukannya tanpa menggunakan Regex seperti ini:

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

Ini adalah opsi yang baik. Jelas dan mudah dibaca.

Namun, Anda dapat melakukan hal yang sama dengan Regex, seperti ini. Tanda kurung digunakan untuk mengelompokkan bagian ekspresi reguler dari pernyataan, tetapi tidak wajib.

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

Panggilan API:

GET http://example.com/matchtest/cat
or
GET http://example.com/matchtest/cat/

Apakah kebijakan dijalankan? Ya. Perhatikan bahwa dalam ekspresi reguler, karakter ? berarti: cocok dengan nol atau salah satu karakter sebelumnya. Oleh karena itu, /cat dan /cat/ cocok.

Panggilan API:

GET http://example.com/matchtest/cat/spotted

Apakah kebijakan dijalankan? Tidak. Ekspresi reguler cocok dengan nol atau hanya satu kemunculan karakter sebelumnya, dan tidak ada yang diizinkan.

Mencocokkan string arbitrer dengan JavaRegex

Dalam semua contoh dalam topik ini, kami menunjukkan cara mencocokkan salah satu variabel alur bawaan: proxy.pathsuffix. Perlu diketahui bahwa Anda dapat melakukan pencocokan pola pada string arbitrer atau variabel alur, baik itu variabel alur bawaan seperti proxy.pathsuffix maupun tidak.

Misalnya, jika Anda memiliki kondisi yang menguji string arbitrer, mungkin string yang ditampilkan dalam payload backend, atau string yang ditampilkan dari pencarian server autentikasi, Anda dapat menggunakan operator pencocokan untuk mengujinya. Jika Anda menggunakan JavaRegex, ekspresi reguler akan dibandingkan dengan seluruh string subjek. Jika subjeknya adalah abc dan ekspresi regulernya adalah [a-z], tidak ada kecocokan, karena [a-z] sama persis dengan satu karakter alfa. Ekspresi [a-z]+ berfungsi, begitu juga dengan [a-z]*, dan [a-z]{3}.

Mari kita lihat contoh konkret. Misalkan server autentikasi menampilkan daftar peran sebagai string yang dipisahkan koma: editor, author, guest.

Untuk menguji keberadaan peran editor, konstruksi ini tidak akan berfungsi, karena editor hanya bagian dari seluruh string.

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

Namun, konstruksi ini akan berfungsi:

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

Fungsi ini berfungsi karena mempertimbangkan jeda kata dan bagian string lainnya dengan awalan dan akhiran .*.

Dalam contoh ini, Anda juga dapat menguji editor dengan operator Matches:

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

Namun, jika Anda memerlukan presisi yang lebih tinggi, JavaRegex sering kali merupakan pilihan yang lebih baik.

Mengelakkan tanda kutip ganda dalam ekspresi JavaRegex

Sintaksis Kondisi mengharuskan ekspresi JavaRegex diapit tanda kutip ganda; oleh karena itu, jika Anda memiliki ekspresi ekspresi reguler yang menyertakan tanda kutip ganda, Anda memerlukan cara alternatif untuk mencocokkannya. Jawabannya adalah Unicode. Misalnya, Anda meneruskan header yang menyertakan tanda kutip ganda, seperti berikut:

 -H 'content-type:multipart/related; type="application/xop+xml"'

Jika Anda mencoba mencocokkan header tersebut dalam kondisi ekspresi reguler, Anda akan mendapatkan error Invalid Condition karena ekspresi tersebut menyertakan tanda kutip ganda:

request.header.Content-Type ~~ "(multipart\/related)(; *type="application\/xop\+xml\")"

Solusinya adalah mengganti tanda kutip ganda berbasis ASCII dengan padanan Unicode-nya, \u0022. Misalnya, ekspresi berikut valid dan menghasilkan hasil yang diharapkan:

request.header.Content-Type ~~ "(multipart\/related)(; *type=\u0022application\/xop\+xml\u0022)"