Halaman ini berlaku untuk Apigee dan Apigee Hybrid.
Baca dokumentasi Apigee Edge.
Pernyataan bersyarat adalah struktur kontrol yang umum dalam semua bahasa pemrograman. Seperti bahasa pemrograman, konfigurasi proxy API mendukung pernyataan bersyarat untuk Alur, Kebijakan, Langkah, dan RouteRules. Dengan menetapkan pernyataan kondisional, Anda menentukan perilaku dinamis untuk API Anda. Dengan perilaku dinamis ini, Anda dapat melakukan hal-hal seperti mengonversi XML menjadi JSON hanya untuk perangkat seluler, atau memilih rute ke URL backend berdasarkan jenis konten atau verb HTTP dari pesan permintaan.
Topik ini menunjukkan cara menggunakan kondisi untuk menerapkan fitur pengelolaan API secara dinamis saat runtime, tanpa perlu menulis kode apa pun.
Mengonfigurasi pernyataan bersyarat
Perilaku kondisional diterapkan di proxy API menggunakan kombinasi conditions dan conditions. Pernyataan kondisional dibuat menggunakan elemen Kondisi. Berikut adalah kondisi kosong:
<Condition></Condition>
Untuk membuat pernyataan bersyarat, tambahkan operator bersyarat 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). Agar mudah dibaca, Anda juga dapat menulis kondisional sebagai
teks: equals
, notequals
, greaterthan
.
Saat menangani 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 bersyarat ke resource API backend. Untuk mengetahui daftar lengkap kondisional, lihat Referensi kondisi.
Variabel
Kondisi melakukan pekerjaannya dengan mengevaluasi nilai variabel. Variabel adalah properti transaksi HTTP yang dijalankan oleh proxy API, atau properti dari konfigurasi proxy API itu sendiri. Setiap kali proxy API mendapat permintaan dari aplikasi, Apigee akan 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. Cara ini menghasilkan konteks lengkap yang dapat Anda gunakan untuk menyiapkan pernyataan bersyarat.
Variabel selalu menggunakan notasi titik-titik. 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 JSON.
Bayangkan Anda perlu membuat pernyataan kondisional yang akan menyebabkan kebijakan hanya diterapkan jika pesan permintaan adalah GET
. Untuk membuat kondisi yang mengevaluasi kata kerja HTTP
sebuah permintaan, buat pernyataan kondisional di bawah ini. Variabel dalam kondisi ini adalah
request.verb
. Nilai variabelnya adalah GET
. Operatornya adalah
=
.
<Condition>request.verb = "GET"</Condition>
Anda juga dapat menggunakan:
<Condition>request.verb equals "GET"</Condition>
Apigee menggunakan pernyataan seperti itu untuk mengevaluasi kondisi. Contoh di atas bernilai benar jika
kata kerja HTTP yang terkait dengan permintaan adalah GET
. Jika kata kerja HTTP yang terkait dengan permintaan adalah
POST
, pernyataan akan bernilai false.
Untuk mengaktifkan perilaku dinamis, Anda dapat melampirkan Kondisi ke Alur, Langkah, dan RouteRules.
Saat melampirkan kondisi ke Alur, Anda akan membuat Alur bersyarat. Alur bersyarat hanya dijalankan saat kondisi bernilai benar (true). Anda dapat melampirkan sebanyak mungkin Kebijakan yang diinginkan ke Flow kondisional. Flow kondisional 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 verb permintaan adalah GET
:
<Flows> <Flow name="ExecuteForGETs"> <Condition>request.verb="GET"</Condition> </Flow> </Flows>
Untuk membuat satu Flow untuk permintaan GET
dan satu Flow 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 Flow kondisional tersebut, Anda dapat melampirkan Kebijakan ke dalamnya, mengaktifkan proxy API
untuk menerapkan satu set kebijakan untuk permintaan GET
, dan kumpulan kebijakan lainnya untuk
permintaan POST
.
Untuk informasi referensi yang komprehensif, lihat referensi berikut:
Contoh 1
Contoh berikut menunjukkan satu alur kondisional bernama Convert-for-devices
, yang dikonfigurasi dalam alur respons ProxyEndpoint. Tambahkan Kondisi sebagai elemen ke entity tempat kondisi tersebut berlaku. Dalam contoh ini, kondisi merupakan komponen alur.
Oleh karena itu, flow akan dieksekusi setiap kali pernyataan bernilai 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 memeriksa nilai variabel request.header.User-Agent
untuk melihat apakah kondisi bernilai benar (true).
Jika kondisinya bernilai true
, yaitu nilai variabel
request.header.User-Agent
sama dengan Mozilla
, Flow bersyarat
akan dijalankan dan kebijakan XMLtoJSON yang disebut ConvertToJSON
akan diterapkan. Jika tidak, Flow
tidak akan dijalankan, dan respons XML akan ditampilkan tanpa modifikasi (dalam format XML) ke aplikasi
yang meminta.
Contoh 2
Mari kita gunakan contoh spesifik di mana Anda perlu mengubah pesan respons dari XML ke JSON—tetapi hanya untuk perangkat seluler. Pertama, buat kebijakan yang akan mengonversi respons berformat XML dari Weather API ke 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 Anda mengonversi pesan request dari XML ke JSON, cukup tetapkan kedua
nilai ini ke request
.)
Karena ingin mengonversi respons dari XML ke JSON, Anda harus mengonfigurasi Alur 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>
Jika Anda memanggil API menggunakan permintaan standar, respons akan diformat dalam JSON.
Namun, sasaran Anda hanya untuk mengonversi laporan Cuaca menjadi JSON saat klien yang meminta adalah perangkat seluler. Untuk mengaktifkan perilaku dinamis tersebut, Anda harus menambahkan pernyataan kondisional ke Flow.
Menguji alur bersyarat
Dalam contoh permintaan ini, header User-Agent
HTTP ditetapkan ke
Mozilla
, yang menyebabkan pernyataan kondisional dievaluasi ke benar (true) dan alur
kondisional Convert-for-devices
akan dijalankan.
curl -H "User-Agent:Mozilla" http://example.com/weather/forecastrss?w=12797282
atau, untuk cukup mencetak di mana 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 dengan
Mozilla
, akan menghasilkan respons berformat XML.
$ curl http://example.com/weather/forecastrss?w=12797282
Respons XML yang tidak dimodifikasi 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 bersyarat:
- Operator
Matches
: Pencocokan pola sederhana - Operator JavaRegex: Kontrol yang lebih mendetail atas pencocokan
- Operator
MatchesPath
: Pencocokan fragmen jalur
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 harfiah, atau lakukan pencocokan karakter pengganti dengan *
. Seperti yang mungkin Anda pikirkan, karakter pengganti cocok dengan nol
atau beberapa karakter. Mari kita lihat
cara kerjanya.
XML berikut menunjukkan kondisi Langkah. Library ini menjalankan kebijakan SomePolicy saat kondisi bernilai benar (true). Dalam contoh ini, kami menguji variabel proxy.pathsuffix
, variabel bawaan di Apigee yang menyimpan akhiran jalur permintaan. Namun, perhatikan bahwa Anda dapat menguji
nilai variabel alur yang berisi string. Jadi, dalam hal ini, 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 Matches "/cat")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
Pertanyaan: Akhiran jalur proxy apa yang akan menyebabkan SomePolicy dijalankan? Hanya ada satu kemungkinan.
Panggilan API:
GET http://example.com/matchtest/cat
Apakah kebijakan tersebut dijalankan? Ya, karena akhiran jalur proxy sama persis dengan /cat
. Fungsi ini tidak akan dijalankan jika akhirannya adalah /bat
atau /dog
atau
/
atau 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 tersebut dijalankan? Ya, karena karakter pengganti cocok dengan karakter apa pun, dan "/cat
" cocok.
Panggilan API:
GET http://example.com/matchtest/bat
Apakah kebijakan tersebut dijalankan? Ya, karena karakter penggantinya cocok dengan karakter apa pun, "/bat"
cocok.
Panggilan API:
GET http://example.com/matchtest/owl
Apakah kebijakan tersebut dijalankan? Tentu saja tidak. Meskipun karakter penggantinya cocok dengan o
, huruf wl
tidak cocok.
Sekarang, mari pindahkan karakter pengganti ke akhir akhiran:
<Condition>(proxy.pathsuffix Matches "/cat*")</Condition>
Panggilan API:
GET http://example.com/matchtest/cat
Apakah kebijakan tersebut dijalankan? Ya, karena karakter pengganti cocok dengan nol atau beberapa karakter apa pun.
Panggilan API:
GET http://example.com/matchtest/bat
Apakah kebijakan tersebut dijalankan? Tidak, /bat
tidak cocok.
Panggilan API:
GET http://example.com/matchtest/cat123
Apakah kebijakan tersebut 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 tersebut dijalankan? Ya, karena karakter pengganti cocok dengan nol atau beberapa karakter, sehingga /bird/mouse
menghasilkan kecocokan. Perhatikan bahwa ekspresi seperti ini dapat menimbulkan masalah karena ekspresi tersebut cocok dengan semuanya setelah karakter literal.
Pertanyaan: Apakah operator Matches
peka huruf besar/kecil?
Ya. Asumsikan Anda memiliki kondisi seperti ini:
<Condition>(proxy.pathsuffix Matches "/*At")</Condition>
Panggilan API:
GET http://example.com/matchtest/cat
Apakah kebijakan tersebut dijalankan? Tidak, karakter pengganti cocok dengan huruf apa pun (terlepas dari besarnya huruf), tetapi a
huruf kecil tidak cocok dengan A
.
Panggilan API:
GET http://example.com/matchtest/bAt
Apakah kebijakan tersebut dijalankan? Ya, kasusnya cocok.
Pertanyaan: Bagaimana cara meng-escape karakter dengan operator Matches
?
Gunakan karakter %
persen untuk menghindari karakter yang dicadangkan. Contoh:
<Condition>(proxy.pathsuffix Matches "/c%*at")</Condition>
Panggilan API:
GET http://example.com/matchtest/cat
Apakah kebijakan tersebut dijalankan? Tidak, operator Matches
mencari string literal c*at
.
Panggilan API:
GET http://example.com/matchtest/c*at
Pertanyaan:Apakah kebijakan dijalankan?
Ya, jalur ini, meskipun sedikit tidak biasa, cocok.
JavaRegex
Seperti yang Anda lihat, operator Matches
sangat cocok untuk situasi sederhana. Namun, Anda dapat menggunakan operator
lain, operator JavaRegex atau ~~
. Keduanya adalah operator yang sama, kecuali JavaRegex
dianggap lebih mudah dibaca. 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 bingung.
Ringkasan: Operator JavaRegex memungkinkan Anda menggunakan sintaksis ekspresi reguler dalam pernyataan bersyarat.
Kode berikut menunjukkan kondisi Langkah. Library ini akan menjalankan kebijakan SomePolicy jika kondisinya
bernilai true
. Dalam contoh ini, kami 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 jalur 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 dijalankan? Sama seperti
operator Matches
, hanya ada satu kemungkinan dalam kasus ini.
Panggilan API:
GET http://example.com/matchtest/cat
Apakah kebijakan tersebut dijalankan? Ya, karena akhiran jalur proxy sama persis dengan /cat
. Fungsi ini tidak akan dijalankan jika akhirannya adalah /bat
atau /dog
atau lainnya.
Sekarang, mari kita buat ekspresi reguler menggunakan kuantifikasi *
. Penghitung 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 tersebut dijalankan? Tidak! Penghitung *
cocok dengan nol atau beberapa
karakter sebelumnya, yaitu c
.
Panggilan API:
GET http://example.com/matchtest/ccccct
Apakah kebijakan tersebut dijalankan? Ya, karena karakter pengganti cocok dengan nol atau beberapa karakter sebelumnya.
Selanjutnya, kita menggunakan kuantifikasi ?
, yang cocok satu kali dengan karakter sebelumnya, atau tidak sama sekali.
<Condition>(proxy.pathsuffix JavaRegex "/ca?t")</Condition>
Panggilan API:
GET http://example.com/matchtest/cat
Apakah kebijakan tersebut dijalankan? Ya. Penghitung ?
cocok dengan nol atau satu kemunculan karakter sebelumnya, yang merupakan a
.
Panggilan API:
GET http://example.com/matchtest/ct
Apakah kebijakan tersebut dijalankan? Ya. Penghitung ?
cocok dengan satu atau tidak sama sekali dari karakter sebelumnya. Dalam hal ini, tidak ada karakter a
, sehingga kondisi bernilai true
.
Panggilan API:
GET http://example.com/matchtest/caat
Apakah kebijakan tersebut dijalankan? Tidak. Penghitung ?
cocok dengan salah satu karakter sebelumnya, yaitu a
.
Selanjutnya, kita menggunakan gaya [abc]
atau pengelompokan ekspresi ekspresi reguler. Karakter ini cocok dengan
karakter a
, b
, atau c
.
<Condition>(proxy.pathsuffix JavaRegex "/[cbr]at")</Condition>
Panggilan API:
GET http://example.com/matchtest/cat
Apakah kebijakan tersebut dijalankan? Ya. Kita menggunakan ekspresi reguler di sini, dan
ekspresi [cbr]
cocok dengan c
, b
, OR r
. Panggilan ini juga cocok:
GET http://example.com/matchtest/bat
GET http://example.com/matchtest/rat
Namun, ini tidak cocok:
GET http://example.com/matchtest/mat
Pertanyaan: Apakah operator JavaRegex peka huruf besar/kecil?
Ya. Asumsikan Anda memiliki kondisi seperti ini:
<Condition>(proxy.pathsuffix JavaRegex "/ca?t")</Condition>
Panggilan API:
GET http://example.com/matchtest/cat
Apakah kebijakan tersebut 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 dijalankan?
Tidak, karena huruf kapital 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 sebuah 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 kita lihat sebuah contoh. Dalam contoh ini, kami menguji variabel proxy.pathsuffix
,
variabel bawaan di Apigee yang menyimpan akhiran jalur permintaan. Namun, perhatikan bahwa Anda dapat
menguji nilai variabel alur 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 dijalankan?
Panggilan API:
GET http://example.com/matchtest/animals
Pertanyaan: Apakah kebijakan dijalankan?
Tidak, karena kondisi memerlukan elemen jalur lain setelah
/animals
, seperti yang ditetapkan oleh /*
.
Panggilan API:
GET http://example.com/matchtest/animals
/
Apakah kebijakan tersebut dijalankan? Ya, jalur tersebut memiliki elemen jalur lain (bagian setelah
/animals/
), tetapi hanya kosong.
Panggilan API:
GET http://example.com/matchtest/animals/cats
Apakah kebijakan tersebut dijalankan? Ya, karena jalur tersebut jelas memiliki elemen (/cats
)
yang berada setelah /animals
Panggilan API:
GET http://example.com/matchtest/animals/cats/wild
Pertanyaan: Apakah kebijakan dijalankan?
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 dijalankan?
Panggilan API:
GET http://example.com/matchtest/animals
Apakah kebijakan tersebut dijalankan? Tidak, karena kondisi memerlukan setidaknya satu elemen jalur berikut
yang ditentukan oleh /**
.
Panggilan API:
GET http://example.com/matchtest/animals
/
Apakah kebijakan ini dijalankan?
Ya, jalur tersebut memiliki elemen jalur lain (bagian setelah
/animals/
), tetapi hanya kosong.
Panggilan API:
GET http://example.com/matchtest/animals/cats
Apakah kebijakan ini dijalankan?
Ya, karena jalur tersebut memiliki setidaknya satu elemen yang muncul setelah
/animals
Panggilan API:
GET http://example.com/matchtest/animals/cats/wild
Apakah kebijakan ini dijalankan?
Ya, karena jalur tersebut memiliki lebih dari satu elemen yang muncul setelah
/animals
Mencampur tanda bintang
Anda dapat menggunakan kombinasi tanda bintang (*) dan ganda (**) untuk lebih mempersempit 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 entity yang dapat diakses developer dengan memanggil API Anda. Misalnya, jika layanan Anda menyediakan laporan cuaca dan perkiraan cuaca, layanan backend mungkin menentukan dua resource API:
http://mygreatweatherforecast.com/reports
http://mygreatweatherforecast.com/forecasts
Saat membuat proxy API (seperti yang ditunjukkan dalam Membangun proxy API pertama Anda), setidaknya Anda membuat URL dasar alias yang memetakan ke layanan backend Anda. Contoh:
URL dasar backend | URL proxy API baru/yang setara |
---|---|
http://mygreatweatherforecast.com |
http://example.com/mygreatweatherforecast |
Pada tahap ini, Anda dapat melakukan panggilan API ke backend menggunakan salah satu URL dasar. Namun, ketika Anda menggunakan URL proxy API, semuanya mulai menarik.
Selain analisis API yang mulai dikumpulkan Apigee saat Anda menggunakan proxy API, proxy juga memungkinkan Anda menentukan alur bersyarat yang dipetakan ke resource di backend Anda. Pada intinya, 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. Salah satunya adalah URL resource yang tidak di-proxy-kan, dan satunya lagi adalah proxy Apigee API dengan alur bersyarat ke resource backend yang sama. Kami akan menjelaskan alur bersyarat secara lebih mendetail di bawah ini.
Cara proxy API dipetakan ke resource backend tertentu
Dengan URL proxy API yang dipetakan ke URL dasar layanan backend (saat membuat
proxy), Anda dapat menambahkan alur bersyarat ke resource tertentu, seperti resource /reports
dan /forecasts
yang disebutkan sebelumnya.
Misalkan Anda ingin Apigee melakukan sesuatu ketika panggilan masuk ke resource /reports
atau /forecasts
. Di tahap ini, Anda tidak memberi tahu Apigee
apa yang harus dilakukan, hanya saja Apigee harus memproses panggilan ke resource tersebut. Anda melakukan ini dengan ketentuan. Di proxy Apigee API, Anda dapat membuat flow 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 menunjukkan, Saat permintaan GET
masuk dengan /reports
dan
/forecasts
di URL, Apigee akan melakukan apa pun yang Anda (developer API) perintahkannya,
melalui kebijakan yang Anda lampirkan ke alur tersebut.
Berikut adalah contoh yang memberi tahu Apigee apa yang harus dilakukan saat suatu kondisi terpenuhi. Dalam XML proxy API berikut, saat permintaan GET
dikirim ke https://example.com/mygreatweatherforecast/reports
, Apigee mengeksekusi 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 flow kondisional opsional tersebut, setiap proxy API juga dilengkapi dengan dua flow
default: <PreFlow>
yang dieksekusi sebelum flow bersyarat, dan
<PostFlow>
yang dieksekusi setelah flow kondisional. Kebijakan tersebut berguna untuk menjalankan kebijakan saat panggilan apa pun dilakukan ke proxy API. Misalnya, jika Anda ingin
memverifikasi kunci API aplikasi dengan setiap panggilan, terlepas dari resource backend yang diakses, Anda
dapat menempatkan kebijakan Verify API Key di <PreFlow>
. Untuk informasi selengkapnya tentang alur, lihat
Mengonfigurasi flow.
Membuat alur bersyarat ke resource backend
Menentukan alur bersyarat ke resource backend dalam proxy API sepenuhnya bersifat opsional. Namun, alur bersyarat tersebut memberi Anda kemampuan untuk menerapkan pengelolaan dan pemantauan yang mendetail.
Anda akan dapat:
- Menerapkan pengelolaan dengan cara yang mencerminkan semantik model API Anda
- Menerapkan kebijakan dan perilaku berskrip ke setiap jalur resource (URI)
- Mengumpulkan metrik terperinci untuk Layanan Analytics
Misalnya, Anda perlu menerapkan berbagai jenis logika ke resource
/developers
backend ke /apps
resource.
Untuk melakukannya, tambahkan dua flow kondisional di proxy API: /developers
dan
/apps
.
Editor Proxy Baru
Untuk menambahkan alur bersyarat:
- Pilih tab Develop di Proxy Editor.
- Pilih Proxy endpoint > default di panel sebelah kiri.
- Klik tombol + di atas panel Response.
- Dalam dialog Add Conditional Flow, masukkan konfigurasi berikut:
- Nama flow:
Developers
- Jenis Ketentuan:
Path
- Jalur:
/developers
Kondisi akan dipicu (dan kebijakan akan dijalankan) jika panggilan dikirim ke proxy dengan
/developers
di akhir URI. - Nama flow:
- Sekarang tambahkan flow kondisional untuk
/apps
, dan asumsikan Anda ingin kondisi tersebut dipicu pada URI dan kata kerjaPOST
dalam permintaan. Konfigurasi melibatkan setelan berikut:- Nama Alur:
Apps
- Jenis Ketentuan:
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 kerjaPOST
. - Nama Alur:
Alur yang ditambahkan ditampilkan di panel Response:
Editor Proxy Klasik
Di panel Develop pada panel Navigator API proxy editor, klik di samping default di Proxy Endpoints.
Di jendela New Conditional Flow, masukkan konfigurasi utama berikut:
- Nama flow:
Developers
- Jenis Ketentuan:
Path
- Jalur:
/developers
Kondisi akan dipicu (dan kebijakan akan dijalankan) jika panggilan dikirim ke proxy dengan /developers
di akhir URI.
Sekarang tambahkan flow kondisional untuk /apps
, dan asumsikan Anda ingin kondisi tersebut dipicu pada URI dan kata kerja POST
dalam permintaan. Konfigurasi melibatkan setelan
berikut:
- Nama Alur:
Apps
- Jenis Ketentuan:
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
.
Di panel Navigator, Anda akan melihat alur baru untuk Apps dan Developers.
Pilih salah satu flow untuk melihat konfigurasi alur bersyarat dalam 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 kondisional yang mengevaluasi jalur URI
permintaan masuk. (Variabel proxy.pathsuffix
mengidentifikasi URI permintaan yang mengikuti BasePath yang dikonfigurasi dalam konfigurasi ProxyEndpoint.)
Setiap resource API yang Anda tentukan diimplementasikan oleh flow bersyarat di proxy API. (Lihat Mengonfigurasi flow.)
Setelah Anda men-deploy proxy API ke lingkungan pengujian, mintalah 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 ke depan (/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 tanda "/" ... di akhir Komunitas Apigee.
Pemodelan URI hierarkis
Dalam beberapa kasus, Anda akan memiliki resource API hierarkis. Misalnya, Developer apps list API menyediakan metode untuk mencantumkan semua aplikasi milik developer. Jalur URI adalah:
/developers/DEVELOPER_EMAIL/apps
Anda mungkin memiliki resource yang membuat ID unik untuk setiap entity dalam koleksi, yang terkadang dianotasikan sebagai berikut:
/genus/:id/species
Jalur ini berlaku secara setara 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
Ini akan menyelesaikan URI hierarki sebagai resource API dengan tepat.
Dalam beberapa kasus, terutama untuk API yang sangat hierarkis, Anda mungkin perlu menyelesaikan semua yang ada 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 menyelesaikan jalur URI berikut:
/developers/DEVELOPER_EMAIL/apps /developers/DEVELOPER_EMAIL/keys /developers/DEVELOPER_EMAIL/apps/APP_ID/keys
Berikut adalah tampilan kondisi alur bersyarat dalam definisi proxy API:
<Condition>(proxy.pathsuffix MatchesPath "/developers/**") and (request.verb = "POST")</Condition>
Contoh lainnya
Condition ditambahkan 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>
Ketentuan 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>
Operator contoh dalam kondisi
Berikut adalah 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 persis ini telah dibahas di
cara mencocokkan terlepas dari apakah ada tanda '/' di akhir URL....
Jika Anda 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 pilihan yang baik. Jelas dan dapat dibaca.
Anda dapat melakukan hal yang sama dengan Regex, tetapi, 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 tersebut 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 tersebut dijalankan? Tidak. Ekspresi reguler cocok dengan nol atau hanya satu kemunculan karakter sebelumnya, dan tidak ada hal lain yang diizinkan.
Mencocokkan string arbitrer dengan JavaRegex
Dalam semua contoh dalam topik ini, kami menunjukkan cara mencocokkan salah satu variabel alur bawaan:
proxy.pathsuffix
. Sebaiknya Anda tahu bahwa Anda dapat melakukan pencocokan pola pada string arbitrer atau
variabel flow apa pun, baik itu variabel alur bawaan seperti proxy.pathsuffix
atau bukan.
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 yang cocok 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 akan ada kecocokan, karena [a-z]
cocok dengan satu karakter alfa. Ekspresi
[a-z]+
berfungsi, seperti halnya [a-z]*
, dan [a-z]{3}
.
Mari kita lihat sebuah 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 merupakan bagian dari seluruh string.
<Condition>returned_roles ~~ "editor"</Condition>
Namun, konstruksi ini akan berfungsi:
<Condition>returned_roles ~~ ".*\beditor\b.*")</Condition>
Metode ini berfungsi karena memperhitungkan jeda kata dan bagian lain dari string dengan awalan dan akhiran .*
.
Dalam contoh ini, Anda juga dapat menguji editor
dengan operator Matches
:
<Condition>returned_roles ~~ "*editor*")</Condition>
Namun, jika Anda membutuhkan lebih banyak presisi, JavaRegex sering kali menjadi pilihan yang lebih baik.
Meng-escape tanda kutip ganda dalam ekspresi JavaRegex
Sintaksis Kondisi memerlukan ekspresi JavaRegex untuk digabungkan dalam tanda kutip ganda. Oleh karena itu, jika 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 mencoba mencocokkan header tersebut dalam kondisi ekspresi reguler, Anda akan mendapatkan error Invalid Condition
karena ekspresi tersebut menyertakan tanda petik 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 memberikan hasil yang diharapkan:
request.header.Content-Type ~~ "(multipart\/related)(; *type=\u0022application\/xop\+xml\u0022)"