Bạn đang xem tài liệu về Apigee Edge.
Chuyển đến
Tài liệu về Apigee X. thông tin
Câu lệnh có điều kiện là một cấu trúc điều khiển phổ biến trong tất cả ngôn ngữ lập trình. Thích ngôn ngữ lập trình, cấu hình proxy API hỗ trợ các câu lệnh có điều kiện cho Luồng, Chính sách, bước và quy tắc định tuyến. Bằng cách xác định câu lệnh có điều kiện, bạn xác định hành vi động cho API của mình. Hành vi động này cho phép bạn thực hiện những việc như chỉ chuyển đổi XML thành JSON cho thiết bị di động hoặc định tuyến đến URL phụ trợ dựa trên loại nội dung hoặc động từ HTTP của thông báo yêu cầu.
Chủ đề này hướng dẫn bạn cách sử dụng các điều kiện để linh động áp dụng các tính năng quản lý API trong thời gian chạy mà không cần viết mã.
Định cấu hình câu lệnh có điều kiện
Hành vi có điều kiện được triển khai trong proxy API bằng cách sử dụng tổ hợp các điều kiện và variables. Câu lệnh có điều kiện được tạo bằng phần tử Điều kiện. Nội dung sau đây là một điều kiện trống:
<Condition></Condition>
Để tạo câu lệnh có điều kiện, bạn thêm một toán tử có điều kiện và một biến để tạo câu lệnh có điều kiện cấu trúc sau:
<Condition>{variable.name}{operator}{"value"}</Condition>
Các toán tử có điều kiện được hỗ trợ bao gồm =
(bằng), !=
(không bằng) và >
(lớn hơn). Để dễ đọc, bạn cũng có thể viết các điều kiện dưới dạng
văn bản: equals
, notequals
, greaterthan
.
Khi làm việc với đường dẫn URI, bạn có thể sử dụng ~/
hoặc MatchesPath
. Bạn cũng có thể khớp biểu thức chính quy JavaRegex với toán tử ~~.
Các điều kiện được dùng để xác định luồng có điều kiện của proxy API tới các tài nguyên API phụ trợ, như mô tả trong phần Tạo luồng có điều kiện đến tài nguyên API phụ trợ. Để biết danh sách đầy đủ các điều kiện, hãy xem phần Tham khảo về điều kiện.
Biến
Điều kiện hoạt động bằng cách đánh giá các giá trị của biến. Biến là một thuộc tính của giao dịch HTTP do proxy API thực thi hoặc là một thuộc tính của chính cấu hình proxy API. Bất cứ khi nào một proxy API nhận được yêu cầu từ một ứng dụng, Apigee Edge sẽ điền sẵn một danh sách dài các biến liên kết với những thứ như thời gian hệ thống, thông tin mạng của ứng dụng, tiêu đề HTTP trên thông báo, cấu hình proxy API, quá trình thực thi chính sách, v.v. Thao tác này sẽ tạo một ngữ cảnh phong phú mà bạn có thể sử dụng để thiết lập câu lệnh có điều kiện.
Các biến luôn sử dụng ký hiệu dấu chấm. Ví dụ: tiêu đề HTTP trên thông báo yêu cầu là
có sẵn dưới dạng biến tên là request.header.{header_name}
. Vì vậy, để đánh giá tiêu đề Content-type (Loại nội dung), bạn có thể sử dụng biến request.header.Content-type
. Để
ví dụ request.header.Content-type = "application/json"
cho biết rằng nội dung
của yêu cầu phải là JSON.
Hãy tưởng tượng bạn cần tạo một câu lệnh có điều kiện để chỉ thực thi chính sách khi thông báo yêu cầu là GET. Để tạo một điều kiện đánh giá động từ HTTP
của yêu cầu, bạn hãy tạo câu lệnh có điều kiện dưới đây. Biến trong điều kiện này là
request.verb
. Giá trị của biến là GET
. Toán tử là
=
.
<Condition>request.verb = "GET"</Condition>Bạn cũng có thể sử dụng:
<Condition>request.verb equals "GET"</Condition>
Edge sử dụng câu lệnh này để đánh giá các điều kiện. Ví dụ trên cho biết giá trị là true (đúng) nếu Động từ HTTP liên kết với yêu cầu là GET. Nếu động từ HTTP liên kết với yêu cầu là POST, thì câu lệnh sẽ có giá trị false.
Để bật hành vi động, bạn có thể đính kèm Điều kiện vào Flows, Steps và RouteRules.
Khi đính kèm một điều kiện vào Luồng, bạn sẽ tạo "Luồng có điều kiện". Luồng có điều kiện chỉ thực thi khi điều kiện có giá trị là true. Bạn có thể đính kèm bao nhiêu Chính sách tuỳ thích vào một Luồng có điều kiện. Luồng có điều kiện cho phép bạn tạo các quy tắc xử lý có tính chuyên môn cao cho các thư yêu cầu hoặc phản hồi đáp ứng các tiêu chí nhất định.
Ví dụ: để tạo một Luồng (Flow) chỉ thực thi khi động từ yêu cầu là GET:
<Flows> <Flow name="ExecuteForGETs"> <Condition>request.verb="GET"</Condition> </Flow> </Flows>
Cách tạo một Flow cho các GET và một Flow cho các POST:
<Flows> <Flow name="ExecuteForGETs"> <Condition>request.verb="GET"</Condition> </Flow> <Flow name="ExecuteForPOSTs"> <Condition>request.verb="POST"</Condition> </Flow> </Flows>
Như trong ví dụ dưới đây, bạn có thể áp dụng điều kiện cho chính Bước chính sách. Chiến lược phát hành đĩa đơn Điều kiện sau khiến Chính sách VerifyApiKey chỉ được thực thi nếu thông báo yêu cầu là ĐĂNG.
<PreFlow name="PreFlow"> <Request> <Step> <Condition>request.verb equals "POST"</Condition> <Name>VerifyApiKey</Name> </Step> </Request> </PreFlow>
Sau khi xác định các Luồng có điều kiện như vậy, bạn có thể đính kèm Chính sách vào các luồng đó, cho phép proxy API thực thi một bộ chính sách cho các yêu cầu GET và một bộ chính sách khác cho các yêu cầu POST.
Để biết thông tin tham khảo đầy đủ, hãy xem các tài nguyên sau:
Ví dụ 1
Ví dụ sau đây cho thấy một luồng có điều kiện duy nhất có tên Convert-for-devices
, được định cấu hình trong luồng phản hồi ProxyEndpoint. Thêm phần tử Điều kiện vào thực thể
mà điều kiện áp dụng. Trong ví dụ này, điều kiện là một thành phần của luồng.
Do đó, flow này sẽ thực thi bất cứ khi nào câu lệnh có kết quả là true.
<Flows> <Flow name="Convert-for-devices"> <Condition>(request.header.User-Agent = "Mozilla")</Condition> <Response> <Step><Name>ConvertToJSON</Name></Step> </Response> </Flow> </Flows>
Đối với mỗi yêu cầu nhận được từ một ứng dụng, Edge lưu trữ giá trị của tất cả các tiêu đề HTTP hiện diện dưới dạng
biến. Nếu yêu cầu chứa tiêu đề HTTP có tên là User-Agent
, thì tiêu đề đó và
giá trị của nó được lưu trữ dưới dạng biến có tên là request.header.User-Agent
.
Với cấu hình ProxyEndpoint ở trên, Edge sẽ kiểm tra giá trị của biến request.header.User-Agent
để xem điều kiện có đánh giá là đúng hay không.
Nếu điều kiện có giá trị là true, tức là giá trị của biến
request.header.User-Agent
bằng Mozilla
, thì Luồng có điều kiện
thực thi và chính sách XMLtoJSON có tên là ConvertToJSON
được thực thi. Nếu không, Luồng sẽ không được thực thi và phản hồi XML sẽ được trả về mà không sửa đổi (ở định dạng XML) cho ứng dụng yêu cầu.
Ví dụ 2
Hãy xem một ví dụ cụ thể, trong đó bạn cần chuyển đổi thông báo phản hồi từ XML thành JSON, nhưng chỉ dành cho thiết bị di động. Trước tiên, hãy tạo chính sách sẽ chuyển đổi Phản hồi ở định dạng XML từ API Thời tiết thành JSON:
<XMLToJSON name="ConvertToJSON"> <Options> </Options> <OutputVariable>response</OutputVariable> <Source>response</Source> </XMLToJSON>
Cấu hình chính sách ở trên cho proxy API nhận thông báo phản hồi, thực hiện một
chuyển đổi từ XML sang JSON với các chế độ cài đặt mặc định, sau đó ghi kết quả vào phản hồi mới
. (Nếu đang chuyển đổi thông báo yêu cầu từ XML sang JSON, bạn chỉ cần đặt cả hai
các giá trị này thành request
.)
Vì muốn chuyển đổi phản hồi từ XML sang JSON, bạn cần định cấu hình một thuộc tính có điều kiện để thực hiện chuyển đổi. Ví dụ: để chuyển đổi tất cả phản hồi từ XML sang JSON trước khi chúng được trả về ứng dụng khách, hãy định cấu hình phản hồi ProxyEndpoint sau đây Quy trình.
<Flows> <Flow name="Convert-for-devices"> <Response> <Step><Name>ConvertToJSON</Name></Step> </Response> </Flow> </Flows>
Khi bạn gọi API bằng yêu cầu thông thường, phản hồi sẽ được định dạng theo định dạng JSON.
Tuy nhiên, mục tiêu của bạn là chỉ chuyển đổi Báo cáo thời tiết thành JSON khi ứng dụng đưa ra yêu cầu là thiết bị di động. Để cho phép hành vi động như vậy, bạn phải thêm câu lệnh có điều kiện vào Quy trình.
Kiểm tra điều kiện luồng
Trong yêu cầu mẫu này, tiêu đề HTTP User-Agent
được đặt thành
Mozilla
, khiến câu lệnh có điều kiện đánh giá thành true và câu lệnh có điều kiện
luồng Convert-for-devices
để thực thi.
$ curl -H "User-Agent:Mozilla" http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282
hoặc để in bản đẹp khi có sẵn Python:
$ curl -H "User-Agent:Mozilla" http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282 | python -mjson.tool
Phản hồi mẫu:
. . . "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" } ] } . . .
Yêu cầu được gửi mà không có tiêu đề User-Agent
hoặc có giá trị khác với Mozilla
sẽ dẫn đến phản hồi ở định dạng XML.
$ curl http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282
Phản hồi XML chưa sửa đổi sẽ được trả về.
Phản hồi mẫu:
<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" />
Phương thức khớp mẫu
Phần này mô tả cách sử dụng tính năng so khớp mẫu với các điều kiện trong luồng Apigee.
Toán tử
Phần này mô tả cách sử dụng các toán tử so khớp mẫu sau trong câu lệnh có điều kiện:
- Toán tử so khớp: So khớp mẫu đơn giản
- Toán tử JavaRegex: Kiểm soát chi tiết hơn việc so khớp
- Toán tử MatchPath: Khớp mảnh đường dẫn
Liên kết
Hãy xem xét các trường hợp hoặc "~" toán tử có điều kiện trước tiên. Hai toán tử này là tương tự -- phiên bản tiếng Anh "Match" (Kết hợp) được coi là lựa chọn dễ đọc hơn.
Tóm tắt: Kết quả "Video trùng khớp" cung cấp cho bạn hai khả năng. Hoặc khớp với hoặc thực hiện khớp ký tự đại diện với "*". Như bạn có thể mong đợi, ký tự đại diện khớp với 0 hoặc nhiều ký tự hơn. Hãy xem cách hoạt động.
XML sau đây cho thấy một điều kiện Bước. Hàm này thực thi chính sách SomePolicy khi điều kiện đánh giá là đúng. Trong ví dụ này, chúng ta kiểm thử biến proxy.pathsuffix
, một biến tích hợp trong Edge lưu trữ hậu tố đường dẫn của yêu cầu. Tuy nhiên, xin lưu ý rằng bạn có thể kiểm thử giá trị của bất kỳ biến flow nào chứa chuỗi. Trong trường hợp này, nếu đường dẫn cơ sở của phương thức
yêu cầu đến là /animals
và yêu cầu là /animals/cat
, sau đó
hậu tố đường dẫn là chuỗi ký tự "/cat
".
<PreFlow name="PreFlow"> <Request> <Step> <Condition>(proxy.pathsuffix Matches "/cat")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
Câu hỏi: Hậu tố đường dẫn proxy nào sẽ khiến somePolicy thực thi? Chỉ có một khả năng.
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/cat
Chính sách có thực thi không? Có, vì hậu tố đường dẫn proxy khớp với "/cat
"
. Hàm này sẽ không thực thi nếu hậu tố là /bat
hoặc /dog
hoặc "/
" hoặc bất kỳ giá trị nào khác.
Bây giờ, hãy xem xét câu lệnh có điều kiện này, trong đó chúng ta sử dụng ký tự đại diện "*
":
<Condition>(proxy.pathsuffix Matches "/*at")</Condition>
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/cat
Chính sách có thực thi không? Có, vì ký tự đại diện khớp với bất kỳ ký tự nào và "/cat
" là một ký tự khớp.
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/bat
Chính sách có thực thi không? Có, vì ký tự đại diện khớp với ký tự bất kỳ, "/bat"
là kết quả trùng khớp.
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/owl
Chính sách có thực thi không? Chắc chắn là không – mặc dù ký tự đại diện khớp với "o
", nhưng chữ cái "wl
" không khớp.
Bây giờ, hãy di chuyển ký tự đại diện đến cuối hậu tố:
<Condition>(proxy.pathsuffix Matches "/cat*")</Condition>
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/cat
Chính sách có thực thi không? Có, vì ký tự đại diện khớp với 0 hoặc nhiều ký tự khác.
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/bat
Chính sách có thực thi không? Không, "/bat
" không khớp.
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/cat123
Chính sách có thực thi không? Có, ký tự đại diện khớp với 0 ký tự trở lên, do đó "123
" sẽ tạo ra kết quả khớp.
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/cat/bird/mouse
Chính sách có thực thi không? Có, vì ký tự đại diện khớp với 0 hoặc nhiều ký tự khác bất kỳ, vì vậy
"/bird/mouse
" sẽ tạo ra kết quả trùng khớp. Hãy lưu ý cách một biểu thức như thế này có thể khiến bạn gặp rắc rối vì nó khớp với mọi thứ sau các ký tự cố định!
Câu hỏi: Toán tử Khớp có phân biệt chữ hoa chữ thường không?
Có. Giả sử bạn có một điều kiện như sau:
<Condition>(proxy.pathsuffix Matches "/*At")</Condition>
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/cat
Chính sách có thực thi không? Không, ký tự đại diện khớp với bất kỳ chữ cái nào (bất kể trường hợp nào), nhưng "a" viết thường không khớp với "A".
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/bAt
Chính sách có thực thi không? Có, trường hợp này trùng khớp.
Câu hỏi: Làm cách nào để ký tự thoát bằng toán tử Khớp?
Sử dụng ký tự phần trăm "%" để thoát các ký tự được đặt trước. Ví dụ:
<Condition>(proxy.pathsuffix Matches "/c%*at")</Condition>
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/cat
Chính sách có thực thi không? Không, toán tử Khớp đang tìm chuỗi cố định "c*at".
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/c*at
Câu hỏi:Chính sách có thực thi không?
Có, đường dẫn này, mặc dù hơi bất thường, nhưng khớp.
JavaRegex
Như bạn có thể thấy, "Video trùng khớp" toán tử phù hợp cho những tình huống đơn giản. Tuy nhiên, bạn có thể sử dụng toán tử "JavaRegex" hoặc "~~" toán tử. Hai toán tử này là cùng một toán tử, ngoại trừ JavaRegex là được coi là dễ đọc hơn. Lớp này được gọi là JavaRegex vì cho phép so khớp mẫu biểu thức chính quy và Edge tuân theo các quy tắc giống như các lớp trong gói java.util.regex bằng ngôn ngữ Java. Cách thức hoạt động của toán tử JavaRegex rất khác với Khớp với toán tử, vì vậy bạn không được nhầm lẫn hai toán tử này!
Tóm tắt: Toán tử "JavaRegex" cho phép bạn sử dụng cú pháp biểu thức chính quy trong các câu lệnh có điều kiện.
Mã sau đây cho thấy một điều kiện Bước. Thao tác này sẽ thực thi chính sách somePolicy nếu điều kiện
có giá trị là true (đúng). Trong ví dụ này, chúng ta kiểm thử biến proxy.pathsuffix
, một biến tích hợp sẵn trong Edge lưu trữ hậu tố đường dẫn của yêu cầu. Nếu đường dẫn cơ sở của
yêu cầu đến là /animals
và yêu cầu là /animals/cat
, sau đó
hậu tố đường dẫn là chuỗi ký tự "/cat
".
<PreFlow name="PreFlow"> <Request> <Step> <Condition>(proxy.pathsuffix JavaRegex "/cat")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
Câu hỏi: Hậu tố đường dẫn proxy nào sẽ khiến somePolicy thực thi? Giống như với toán tử Khớp, trong trường hợp này, chỉ có một khả năng.
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/cat
Chính sách có thực thi không? Có, vì hậu tố đường dẫn proxy khớp chính xác với "/cat
". Thao tác này sẽ không thực thi nếu hậu tố là /bat
, /dog
hoặc bất kỳ giá trị nào
khác.
Bây giờ, hãy tạo một biểu thức chính quy bằng toán tử lượng từ "*". Bộ lượng từ này khớp với từ 0 ký tự trở lên trước đó.
<Condition>(proxy.pathsuffix JavaRegex "/c*t")</Condition>
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/cat
Chính sách có thực thi không? Không đâu! Ký hiệu "*" bộ định lượng khớp với 0 hoặc nhiều giá trị
ký tự đứng trước, là "c
".
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/ccccct
Chính sách có thực thi không? Có, vì ký tự đại diện khớp với 0 hoặc nhiều ký tự trước đó.
Tiếp theo, chúng tôi sử dụng "?
" bộ định lượng, khớp với ký tự trước đó một lần hoặc không
nào.
<Condition>(proxy.pathsuffix JavaRegex "/ca?t")</Condition>
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/cat
Chính sách có thực thi không? Có. "?
" bộ định lượng khớp với không hoặc một lần xuất hiện của
ký tự trước, là "a
".
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/ct
Chính sách có thực thi không? Có. Bộ lượng từ "?
" khớp với một hoặc không khớp với ký tự trước đó. Trong trường hợp này, không có "a" nên ký tự
điều kiện có giá trị là true (đúng).
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/caat
Chính sách có thực thi không? Không. Toán tử lượng từ "?" khớp với một ký tự trước đó, đó là "a
".
Tiếp theo, chúng tôi sử dụng "[abc]
" hoặc "nhóm" kiểu biểu thức chính quy. URL này khớp với
ký tự "a
" hoặc "b
" hoặc "c
".
<Condition>(proxy.pathsuffix JavaRegex "/[cbr]at")</Condition>
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/cat
Chính sách có thực thi không? Có. Chúng tôi đang sử dụng biểu thức chính quy ở đây, và
"[cbr]
" khớp với "c", "b", HOẶC "r". Những lệnh gọi này cũng khớp:
GET http://artomatic-test.apigee.net/matchtest/bat
GET http://artomatic-test.apigee.net/matchtest/rat
Nhưng đây không phải là kết quả trùng khớp:
GET http://artomatic-test.apigee.net/matchtest/mat
Câu hỏi: Toán tử JavaRegex có phân biệt chữ hoa chữ thường không?
Có. Giả sử bạn có một điều kiện như sau:
<Condition>(proxy.pathsuffix JavaRegex "/ca?t")</Condition>
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/cat
Chính sách có thực thi không? Có, biểu thức chính quy khớp với 0 hoặc 1 ký tự trước đó, đó là "a".
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/cAt
Câu hỏi: Chính sách có thực thi không?
Không, vì chữ "A" viết hoa không khớp với chữ "a" viết thường.
MatchesPath
Bạn cũng có thể chỉ định toán tử MatchesPath
như thế này "~/". Ứng dụng này có vẻ hơi giống
Matches
(~) và các toán tử JavaRegex (~~). Tuy nhiên, MatchPath hoàn toàn khác.
Chỉ cần nhớ rằng toán tử này xem một đường dẫn là một loạt các phần. Do đó, nếu đường dẫn là: /animals/cats/wild
, bạn có thể coi đường dẫn này bao gồm các phần "/animals
", "/cats
" và "/wild
".
Toán tử MatchesPath
cho phép bạn sử dụng hai ký hiệu đại diện: một dấu hoa thị đơn (*) và một dấu hoa thị đôi (**). Dấu hoa thị đơn khớp với một phần tử đường dẫn. Dấu hoa thị đôi khớp với một hoặc nhiều phần tử đường dẫn.
Hãy xem ví dụ. Trong ví dụ này, chúng ta kiểm thử biến proxy.pathsuffix
, một biến tích hợp trong Edge lưu trữ hậu tố đường dẫn của yêu cầu. Tuy nhiên, bạn có thể
thử nghiệm giá trị của bất kỳ biến luồng nào chứa chuỗi.
<PreFlow name="PreFlow"> <Request> <Step> <Condition>(proxy.pathsuffix MatchesPath "/animals/*")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
Câu hỏi: Hậu tố đường dẫn proxy nào sẽ khiến somePolicy thực thi?
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/animals
Câu hỏi: Chính sách có thực thi không?
Không, vì điều kiện yêu cầu một phần tử đường dẫn khác sau
"/animals
", như được chỉ định bởi "/*
".
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/animals
/
Chính sách có thực thi không? Có, đường dẫn có một phần tử đường dẫn khác (phần phía sau
"/animals/
"), nhưng chỉ trống.
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/animals/cats
Chính sách có thực thi không? Có, vì đường dẫn rõ ràng chứa một phần tử ("/cats
")
đứng sau "/animals
"
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild
Câu hỏi: Chính sách có thực thi không?
Không, vì dấu hoa thị đơn chỉ khớp với một phần tử đường dẫn và API này có nhiều phần tử sau "/animals
".
Bây giờ, hãy sử dụng dấu hoa thị kép:
<PreFlow name="PreFlow"> <Request> <Step> <Condition>(proxy.pathsuffix MatchesPath "/animals/**")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
Câu hỏi: Hậu tố đường dẫn proxy nào sẽ khiến SomePolicy thực thi?
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/animals
Chính sách có thực thi không? Không, vì điều kiện yêu cầu ít nhất một phần tử đường dẫn sau
do "/**
" chỉ định.
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/animals
/
Chính sách có thực thi không?
Có, đường dẫn có một phần tử đường dẫn khác (phần phía sau
"/animals/
"), nhưng chỉ trống.
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/animals/cats
Chính sách này có thực thi không?
Có, vì đường dẫn có ít nhất một phần tử đứng sau
"/animals
"
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild
Chính sách có thực thi không?
Có, vì đường dẫn này có nhiều phần tử đứng sau
"/animals
"
Kết hợp dấu hoa thị
Bạn có thể sử dụng kết hợp dấu hoa thị đơn (*) và dấu hoa thị đôi (**) để tinh chỉnh thêm tính năng so khớp đường dẫn.
<PreFlow name="PreFlow"> <Request> <Step> <Condition>(proxy.pathsuffix MatchesPath "/animals/*/wild/**")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
Lệnh gọi API:
Tất cả các lệnh gọi API này sẽ tạo ra một kết quả trùng khớp:
GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild/
và
GET http://artomatic-test.apigee.net/matchtest/animals/dogs/wild/austrailian
và
GET
http://artomatic-test.apigee.net/matchtest/animals/birds/wild/american/finches
Tài nguyên API
Dịch vụ RESTful là tập hợp tài nguyên API. Tài nguyên API là một mảnh đường dẫn URI xác định một số thực thể mà nhà phát triển có thể truy cập bằng cách gọi API của bạn. Ví dụ: nếu dịch vụ của bạn cung cấp báo cáo thời tiết và dự báo thời tiết thì dịch vụ phụ trợ của bạn có thể xác định 2 tài nguyên API:
- http://mygreatweatherforecast.com/reports
- http://mygreatweatherforecast.com/forecasts
Khi tạo một proxy API (như trong phần Tạo proxy API đầu tiên), ít nhất bạn cũng đang tạo một URL cơ sở của bí danh liên kết đến dịch vụ phụ trợ của mình. Ví dụ:
URL cơ sở của phần phụ trợ | URL proxy API mới/tương đương |
---|---|
http://mygreatweatherforecast.com | http://{your_org}-{environment}.apigee.net/mygreatweatherforecast |
Tại thời điểm này, bạn có thể thực hiện lệnh gọi API đến phần phụ trợ bằng cách sử dụng URL cơ sở. Nhưng khi bạn sử dụng URL proxy API, mọi thứ bắt đầu trở nên thú vị.
Ngoài dữ liệu phân tích API mà Edge bắt đầu thu thập khi bạn sử dụng proxy API, proxy cũng cho phép bạn xác định các luồng có điều kiện liên kết với các tài nguyên trên phần phụ trợ. Về cơ bản, "Nếu một lệnh gọi GET đến với tài nguyên /reports, Edge sẽ phải thực hiện một việc gì đó".
Hình ảnh sau đây cho thấy sự khác biệt về hành vi giữa hai URL cuối cùng truy cập vào cùng một chương trình phụ trợ. Một là URL tài nguyên không bị proxy, URL còn lại là proxy API của Edge có luồng có điều kiện đến cùng một tài nguyên phụ trợ. Chúng ta sẽ mô tả chi tiết hơn về luồng có điều kiện ở bên dưới.
Cách proxy API liên kết với các tài nguyên phụ trợ cụ thể
Với URL proxy API được liên kết với URL cơ sở của dịch vụ phụ trợ (khi bạn tạo proxy), bạn có thể thêm các luồng có điều kiện vào các tài nguyên cụ thể, chẳng hạn như tài nguyên /reports
và /forecasts
được đề cập trước đó.
Giả sử bạn muốn Edge "làm gì đó" khi có lệnh gọi đến tài nguyên /reports
hoặc /forecasts
. Tại thời điểm này, bạn không cho Edge biết nên làm gì, mà chỉ cần Edge nghe các lệnh gọi đến các tài nguyên đó. Bạn thực hiện việc này bằng các điều kiện. Trong proxy API Edge, bạn có thể tạo flow có điều kiện cho /reports
và /forecasts
. Đối với mục đích khái niệm, tệp XML proxy API sau đây cho thấy những điều kiện đó có thể trông như thế nào.
<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>
Các điều kiện đó cho biết "Khi yêu cầu GET gửi đến /reports
và
/forecasts
trong URL, Edge sẽ làm bất cứ việc gì mà bạn (nhà phát triển API) yêu cầu,
thông qua chính sách bạn đính kèm với các quy trình đó.
Sau đây là ví dụ về cách yêu cầu Edge thực hiện hành động khi một điều kiện được đáp ứng. Trong API sau
XML proxy, khi một yêu cầu GET được gửi đến
https://yourorg-test.apigee.net/mygreatweatherforecast/reports
, Edge thực thi
"XML thành JSON-1" trong phản hồi.
<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>
Ngoài các luồng có điều kiện không bắt buộc đó, mỗi proxy API cũng đi kèm với hai luồng mặc định: <PreFlow>
được thực thi trước luồng có điều kiện và <PostFlow>
được thực thi sau luồng có điều kiện. Đó là những thông tin hữu ích cho
thực thi chính sách khi bất kỳ lệnh gọi nào được thực hiện đến proxy API. Ví dụ: nếu muốn xác minh khoá API của ứng dụng bằng mọi lệnh gọi, bất kể tài nguyên phụ trợ nào đang được truy cập, bạn có thể đặt chính sách Xác minh khoá API trên <PreFlow>
. Để tìm hiểu thêm về luồng, hãy xem
Định cấu hình luồng.
Tạo luồng có điều kiện đến tài nguyên phụ trợ
Bạn hoàn toàn không bắt buộc phải xác định luồng có điều kiện đến các tài nguyên phụ trợ trong proxy API. Tuy nhiên, các luồng có điều kiện đó cho phép bạn áp dụng tính năng quản lý và giám sát chi tiết.
Bạn sẽ có thể:
- Áp dụng quy trình quản lý theo cách phản ánh ngữ nghĩa của mô hình API
- Áp dụng chính sách và hành vi theo tập lệnh cho từng đường dẫn tài nguyên (URI)
- Thu thập các chỉ số chi tiết cho Dịch vụ Analytics
Ví dụ: giả sử bạn cần áp dụng nhiều loại logic cho phần phụ trợ /developers sang tài nguyên /apps.
Để thực hiện việc này, bạn cần thêm 2 luồng có điều kiện vào proxy API: /developers
và
/apps
.
Trong chế độ xem Phát triển của ngăn Trình điều hướng của trình chỉnh sửa proxy API, hãy nhấp vào biểu tượng dấu + bên cạnh giá trị mặc định trong Điểm cuối proxy.
Trong "Luồng có điều kiện mới" bạn sẽ nhập các cấu hình khoá sau:
- Tên quy trình: Nhà phát triển
- Loại điều kiện: Đường dẫn
- Đường dẫn: /developers
Điều kiện sẽ được kích hoạt (và các chính sách sẽ được thực thi) nếu một cuộc gọi được gửi đến proxy với /developers ở cuối URI.
Bây giờ, hãy thêm một luồng có điều kiện cho /apps và giả sử bạn muốn điều kiện được kích hoạt trên cả URI và động từ POST trong một yêu cầu. Cấu hình này liên quan đến việc thiết lập các thông tin sau:
- Tên luồng: Ứng dụng
- Loại điều kiện: Đường dẫn và động từ
- Đường dẫn: /apps
- Động từ: POST
Điều kiện này sẽ được kích hoạt (và các chính sách sẽ được thực thi) nếu một lệnh gọi được gửi đến proxy với /apps ở cuối URI và một động từ POST.
Trong ngăn Navigator (Trình điều hướng), bạn sẽ thấy các luồng mới cho Apps (Ứng dụng) và Nhà phát triển.
Chọn một trong các quy trình để xem cấu hình luồng có điều kiện trong trình chỉnh sửa proxy API chế độ xem mã:
<Flow name="Apps"> <Description>Developer apps registered in Developer Services</Description> <Request/> <Response/> <Condition>(proxy.pathsuffix MatchesPath "/apps") and (request.verb = "POST")</Condition> </Flow>
Như bạn có thể thấy, tài nguyên API chỉ đơn giản là các Luồng có điều kiện đánh giá đường dẫn URI của yêu cầu đến. (Biến proxy.pathsuffix xác định URI của yêu cầu diễn ra sau BasePath được định cấu hình trong cấu hình ProxyEndpoint.)
Mỗi tài nguyên API mà bạn xác định được triển khai bằng một Luồng có điều kiện trong proxy API. (Xem phần Định cấu hình luồng.)
Sau khi bạn triển khai proxy API cho môi trường kiểm thử, hãy thực hiện yêu cầu sau:
http://{org_name}-test.apigee.net/{proxy_path}/apps
sẽ khiến điều kiện đánh giá là đúng và luồng này, cùng với mọi chính sách liên quan, sẽ thực thi.
Điều kiện ví dụ sau đây sử dụng một biểu thức chính quy Java để nhận dạng các lệnh gọi đến phương thức
Tài nguyên /apps
có hoặc không có dấu gạch chéo lên ở cuối (/apps
hoặc
/apps/**
):
<Condition>(proxy.pathsuffix JavaRegex "/apps(/?)") and (request.verb = "POST")</Condition>
Để biết thêm về loại điều kiện này, hãy xem bài viết Cách so khớp bất kể ... trong Cộng đồng Apigee.
Mô hình hoá URI phân cấp
Trong một số trường hợp, bạn sẽ có tài nguyên API phân cấp. Ví dụ: Dịch vụ dành cho nhà phát triển API cung cấp phương thức liệt kê tất cả ứng dụng của một nhà phát triển. Đường dẫn URI là:
/developers/{developer_email}/apps
Một số tài nguyên của bạn có thể được tạo một mã nhận dạng duy nhất cho mỗi thực thể trong một tập hợp. Điều này đôi khi được chú thích như sau:
/genus/:id/species
Đường dẫn này áp dụng như nhau cho hai URI sau:
/genus/18904/species /genus/17908/species
Để biểu thị cấu trúc này trong tài nguyên API, bạn có thể dùng ký tự đại diện. Ví dụ:
/developers/*/apps
/developers/*example.com/apps
/genus/*/species
sẽ phân giải các URI phân cấp này dưới dạng tài nguyên API một cách phù hợp.
Trong một số trường hợp, đặc biệt là đối với các API phân cấp sâu, bạn có thể chỉ muốn giải quyết mọi thứ bên dưới mảnh URI nhất định. Để thực hiện việc này, hãy sử dụng ký tự đại diện dấu hoa thị kép trong định nghĩa tài nguyên của bạn. Để ví dụ: nếu bạn xác định tài nguyên API sau:/developers/**
Tài nguyên API đó sẽ phân giải các đường dẫn URI sau:
/developers/{developer_email}/apps /developers/{developer_email}/keys /developers/{developer_email}/apps/{app_id}/keys
Dưới đây là ví dụ về điều kiện luồng có điều kiện trong định nghĩa proxy API:
<Condition>(proxy.pathsuffix MatchesPath "/developers/**") and (request.verb = "POST")</Condition>
Ví dụ khác
Điều kiện được đính kèm vào 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>
Điều kiện đi kèm với chính sách
<Step> <!--the policy MaintenancePolicy only executes if the response status code is exactly 503--> <Condition>response.status.code = 503</Condition> <Name>MaintenancePolicy</Name> </Step>
Luồng có điều kiện
<!-- 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>
Toán tử mẫu trong các điều kiện
Dưới đây là một số ví dụ về các toán tử dùng để tạo điều kiện:
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
Ví dụ thực tế: Bỏ qua "/" ở cuối đường dẫn
Các nhà phát triển ứng dụng Edge thường muốn xử lý cả hai hậu tố đường dẫn sau: "/cat
" và
"/cat/
". Điều này là do một số người dùng hoặc ứng dụng có thể gọi API của bạn bằng hàm bổ sung
dấu gạch chéo ở cuối đường dẫn và bạn cần có thể xử lý điều đó trong
tuyên bố. Trường hợp sử dụng chính xác này đã được thảo luận trên Cộng đồng Apigee.
Nếu muốn, bạn có thể làm được điều này mà không cần sử dụng Regex như sau:
<PreFlow name="PreFlow"> <Request> <Step> <Condition>((proxy.pathsuffix = "/cat") OR (proxy.pathsuffix = "/cat/")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
Đây là một lựa chọn hay. Rõ ràng và dễ đọc.
Tuy nhiên, bạn có thể làm tương tự với Regex như sau. Dấu ngoặc đơn được dùng để nhóm phần biểu thức chính quy của câu lệnh, nhưng không bắt buộc.
<Condition>(proxy.pathsuffix JavaRegex "/cat(/?)"</Condition>
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/cat
or
GET http://artomatic-test.apigee.net/matchtest/cat
/
Chính sách có thực thi không? Có. Xin lưu ý rằng trong biểu thức chính quy, ký tự "?
" có nghĩa là: khớp với 0 hoặc 1 ký tự trước đó. Do đó, cả hai
"/cat
" và "/cat/
" là kết quả phù hợp.
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/cat/spotted
Chính sách có thực thi không? Không. Biểu thức chính quy khớp với 0 hoặc chỉ một lần xuất hiện của ký tự trước đó và không được phép khớp với bất kỳ ký tự nào khác.
So khớp các chuỗi tuỳ ý với JavaRegex
Trong tất cả ví dụ về chủ đề này, chúng tôi sẽ trình bày cách so khớp một trong các biến luồng tích hợp sẵn: proxy.pathsuffix. Bạn nên biết rằng bạn có thể so khớp mẫu trên bất kỳ chuỗi tuỳ ý nào hoặc biến flow, cho dù đó có phải là biến flow tích hợp sẵn như proxy.pathsuffix hay không.
Chẳng hạn, nếu bạn có một điều kiện kiểm thử một chuỗi tuỳ ý, thì có thể là một chuỗi được trả về trong tải trọng phụ trợ hoặc một chuỗi được trả về từ quá trình tra cứu máy chủ xác thực, bạn có thể sử dụng các toán tử so khớp để kiểm tra nó. Nếu bạn sử dụng JavaRegex, biểu thức chính quy sẽ được so sánh với toàn bộ chuỗi chủ đề. Nếu tiêu đề là "abc" và biểu thức chính quy là "[a-z]", thì sẽ không có kết quả phù hợp vì "[a-z]" khớp chính xác với một ký tự chữ cái. Biểu thức "[a-z]+" hoạt động, cũng như "[a-z]*" và "[a-z]{3}".
Hãy xem một ví dụ cụ thể. Giả sử máy chủ xác thực trả về một danh sách các vai trò dưới dạng chuỗi được phân tách bằng dấu phẩy: "người chỉnh sửa, tác giả, khách".
Để kiểm tra sự hiện diện của vai trò người chỉnh sửa, cấu trúc này sẽ không hoạt động vì "editor" chỉ là một phần của toàn bộ chuỗi.
<Condition>returned_roles ~~ "editor"</Condition>
Tuy nhiên, cấu trúc này sẽ hoạt động:
<Condition>returned_roles ~~ ".*\beditor\b.*")</Condition>
Phương thức này hiệu quả vì nó tính đến các ngắt từ và bất kỳ phần nào khác của chuỗi có ký tự .* tiền tố và hậu tố.
Trong ví dụ này, bạn cũng có thể kiểm thử "người chỉnh sửa" bằng toán tử Match:
<Condition>returned_roles ~~ "*editor*")</Condition>
Tuy nhiên, trong trường hợp bạn cần độ chính xác cao hơn, JavaRegex thường là lựa chọn tốt hơn.
Thoát dấu ngoặc kép trong biểu thức JavaRegex
Cú pháp Điều kiện yêu cầu biểu thức JavaRegex phải được đặt trong dấu ngoặc kép; do đó, nếu bạn có một Biểu thức chính quy bao gồm dấu ngoặc kép, bạn cần có một cách khác để so khớp biểu thức đó. Câu trả lời là Unicode. Ví dụ: giả sử bạn truyền vào một tiêu đề có chứa dấu ngoặc kép, như sau:-H 'content-type:multipart/related; type="application/xop+xml"'Nếu cố gắng so khớp tiêu đề đó trong điều kiện Regex, bạn sẽ gặp lỗi Điều kiện không hợp lệ vì biểu thức có chứa dấu ngoặc kép:
request.header.Content-Type ~~ "(multipart\/related)(; *type="application\/xop\+xml\")"Giải pháp là thay thế dấu ngoặc kép dựa trên ASCII bằng ký tự tương đương Unicode,
\u0022
. Ví dụ:
biểu thức sau hợp lệ và cho ra kết quả như mong đợi:
request.header.Content-Type ~~ "(multipart\/related)(; *type=\u0022application\/xop\+xml\u0022)"