Bạn đang xem tài liệu về Apigee Edge.
Chuyển đến
tài liệu về Apigee X. info
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. Giống như một 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ác 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 linh động này cho phép bạn thực hiện những việc như chuyển đổi XML thành JSON chỉ 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 để áp dụng linh độ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 kết hợp điều kiện và biến. Câu lệnh có điều kiện được tạo bằng phần tử Condition. 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 trúc sau:
<Condition>{variable.name}{operator}{"value"}</Condition>
Các toán tử đ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ể so khớp biểu thức chính quy JavaRegex bằng toán tử ~~.
Điều kiện được dùng để xác định luồng có điều kiện của proxy API cho tài nguyên API phụ trợ, được mô tả trong phần Tạo luồng có điều kiện cho tài nguyên API phụ trợ. Để xem danh sách đầy đủ các điều kiện, hãy xem Tài liệu tham khảo về điều kiện.
Biến
Điều kiện hoạt động bằng cách đánh giá 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à thuộc tính của chính cấu hình proxy API. Bất cứ khi nào proxy API nhận được yêu cầu từ một ứng dụng, Apigee Edge sẽ điền vào một danh sách dài các biến liên quan đến những thông tin 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, việc thực thi chính sách, v.v. Thao tác này sẽ tạo ra một bối cảnh phong phú mà bạn có thể dùng để thiết lập các câu lệnh có điều kiện.
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 có sẵn dưới dạng các biến có tên là request.header.{header_name}. Vì vậy, để đánh giá tiêu đề Content-type, bạn có thể sử dụng biến request.header.Content-type. Ví dụ: request.header.Content-type = "application/json" cho biết loại nội dung của yêu cầu phải là JSON.
Hãy tưởng tượng rằng bạn cần tạo một câu lệnh có điều kiện để khiến một chính sách chỉ được thực thi 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 một yêu cầu, bạn tạo câu lệnh có điều kiện bên dưới. 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>
<Condition>request.verb equals "GET"</Condition>
Edge sử dụng câu lệnh như vậy để đánh giá các điều kiện. Ví dụ trên sẽ cho kết quả là true 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ị là false.
Để bật hành vi động, bạn có thể đính kèm Điều kiện vào Luồng, Bước và Quy tắc định tuyến.
Khi đính kèm một điều kiện vào một Luồng, bạn sẽ tạo ra một "Luồng có điều kiện". Luồng có điều kiện chỉ thực thi khi điều kiện được đánh giá là đúng. 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ý chuyên biệt cao cho các thông báo yêu cầu hoặc phản hồi đáp ứng một số tiêu chí nhất định.
Ví dụ: để tạo một 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 GET và một Flow khác cho 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ụ bên dưới, bạn có thể áp dụng điều kiện cho chính Bước chính sách. Điều kiện sau đây khiến Chính sách VerifyApiKey chỉ được thực thi nếu thông báo yêu cầu là POST.
<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 nhóm chính sách cho các yêu cầu GET và một nhóm chính sách khác cho các yêu cầu POST.
Để biết thông tin tham khảo toàn diện, 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 là Convert-for-devices, được định cấu hình trong luồng phản hồi ProxyEndpoint. Thêm Điều kiện làm phần tử cho 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 quy trình.
Do đó, quy trình sẽ thực thi bất cứ khi nào câu lệnh cho 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 sẽ lưu trữ giá trị của tất cả tiêu đề HTTP hiện có 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 tiêu đề sẽ được lưu trữ dưới dạng một 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ó được đánh giá là đúng hay không.
Nếu điều kiện được đánh giá là đúng, tức là giá trị của biến
request.header.User-Agent bằng Mozilla, thì Luồng có điều kiện
sẽ thực thi và chính sách XMLtoJSON có tên là ConvertToJSON sẽ được thực thi. Nếu không, Flow sẽ không được thực thi và phản hồi XML sẽ được trả về mà không được 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 sang 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 có định dạng XML từ Weather API 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 yêu cầu proxy API lấy thông báo phản hồi, thực hiện chuyển đổi từ XML sang JSON bằng chế độ cài đặt mặc định, sau đó ghi kết quả vào thông bá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 giá trị này thành request.)
Vì muốn chuyển đổi phản hồi từ XML sang JSON, nên bạn cần định cấu hình Luồng phản hồi có điều kiện để thực hiện việc chuyển đổi. Ví dụ: để chuyển đổi tất cả phản hồi từ XML sang JSON trước khi trả về ứng dụng khách, hãy định cấu hình Flow phản hồi ProxyEndpoint sau đây.
<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 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 yêu cầu là một thiết bị di động. Để bật hành vi động như vậy, bạn phải thêm một câu lệnh có điều kiện vào Flow.
Kiểm thử quy trình có điều kiện
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 được đánh giá là đúng và luồng có điều kiện Convert-for-devices được thực thi.
$ curl -H "User-Agent:Mozilla" http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282
hoặc để tạo bản in đẹp khi có 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 có đị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 một 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 đây trong câu lệnh có điều kiện:
- Toán tử khớp: Khớp mẫu đơn giản
- Toán tử JavaRegex: Kiểm soát chặt chẽ hơn việc so khớp
- Toán tử MatchesPath: So khớp mảnh đường dẫn
Liên kết
Trước tiên, hãy xem toán tử điều kiện "Khớp" hoặc "~". Hai toán tử này giống nhau, nhưng phiên bản tiếng Anh "Matches" được coi là dễ đọc hơn.
Tóm tắt: Toán tử "Khớp" mang đến cho bạn hai khả năng. Khớp chính xác chuỗi hoặc khớp ký tự đại diện bằng "*". Như bạn có thể đoán, ký tự đại diện khớp với 0 hoặc nhiều ký tự. Hãy cùng tìm hiểu cách hoạt động của tính năng này.
XML sau đây cho thấy một điều kiện Bước. Nó thực thi chính sách SomePolicy khi điều kiện được đánh giá là đúng. Trong ví dụ này, chúng ta kiểm thử biến proxy.pathsuffix, một biến được tạo sẵn 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 tra giá trị của bất kỳ biến luồng nào chứa chuỗi. Vì vậy, trong trường hợp này, nếu đường dẫn cơ sở của yêu cầu đến là /animals và yêu cầu là /animals/cat, thì 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 chính xác 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 quả 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 bất kỳ ký tự nào, nên "/bat" là một kết quả 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 các 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ó được thực thi không? Có, vì ký tự đại diện khớp với không hoặc nhiều ký tự bất kỳ.
Lệnh gọi API:
GET http://artomatic-test.apigee.net/matchtest/bat
Chính sách có đượ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 hoặc nhiều ký tự bất kỳ, 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ó được thực thi không? Có, vì ký tự đại diện khớp với 0 hoặc nhiều ký tự bất kỳ, nên "/bird/mouse" sẽ tạo ra kết quả khớp. Hãy lưu ý rằng một biểu thức như thế này có thể khiến bạn gặp rắc rối vì biểu thức này 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 mọi chữ cái (bất kể cách viết hoa), nhưng chữ "a" viết thường không khớp với chữ "A" viết hoa.
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 khớp.
Câu hỏi: Làm cách nào để thoát ký tự bằng toán tử Khớp?
Sử dụng ký tự phần trăm "%" để thoát các ký tự dành riêng. 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 ký tự "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ó được thực thi không?
Đúng vậy, đường dẫn này khớp, mặc dù hơi khác thường.
JavaRegex
Như bạn có thể thấy, toán tử "Khớp" rất phù hợp cho các trường hợp đơn giản. Tuy nhiên, bạn có thể sử dụng một toán tử khác, toán tử "JavaRegex" hoặc "~~". Hai toán tử này giống nhau, ngoại trừ việc JavaRegex được coi là dễ đọc hơn. Chính sách 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 trong ngôn ngữ Java. Cách hoạt động của toán tử JavaRegex rất khác với toán tử Matches, vì vậy, bạn cần lưu ý để không nhầm lẫn giữa 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.
Đoạn mã sau đây cho thấy một điều kiện của Bước. Nó thực thi chính sách SomePolicy nếu điều kiện được đánh giá là true. 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, thì 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? Cũng giống như toán tử Matches, chỉ có một khả năng trong trường hợp này.
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". Hàm này sẽ không thực thi nếu hậu tố là /bat hoặc /dog hoặc bất kỳ hậu tố nào khác.
Bây giờ, hãy tạo một biểu thức chính quy bằng cách sử dụng bộ định lượng "*". Bộ định lượng này khớp với không hoặc nhiều ký tự đứng 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! Bộ định lượng "*" khớp với 0 hoặc nhiều ký tự đứng trước, tứ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 không hoặc nhiều ký tự đứng trước.
Tiếp theo, chúng ta sử dụng bộ định lượng "?" để so khớp ký tự đứng trước một lần hoặc không so khớp.
<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 0 hoặc 1 lần xuất hiện của ký tự đứng trước, tứ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ộ định lượng "?" khớp với một hoặc không có ký tự nào đứng trước. Trong trường hợp này, không có ký tự "a" nên điều kiện được đánh giá là đú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. Bộ định lượng "?" khớp với một ký tự đứng trước, tức là "a".
Tiếp theo, chúng ta sử dụng kiểu biểu thức chính quy "[abc]" hoặc "nhóm". Biểu thức này khớp với các 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 ta đang sử dụng biểu thức chính quy ở đây và biểu thức "[cbr]" khớp với "c", "b" HOẶC "r". Những cuộc gọi sau đây cũng là cuộc gọi trù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 không hoặc một ký tự đứng trước, tứ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ó đượ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ư "~/". Toán tử này có vẻ giống với toán tử Matches (~) và JavaRegex (~~). Nhưng MatchesPath hoàn toàn khác.
Hãy nhớ rằng toán tử này xem xét một đường dẫn dưới dạng một chuỗi các phần. Do đó, nếu đường dẫn là: /animals/cats/wild, bạn có thể coi đường dẫn 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ị (*) và hai dấu hoa thị (**). Một dấu hoa thị khớp với một phần tử đường dẫn. Dấu hoa thị kép 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 được tạo sẵn 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 tra 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ó đượ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 sau
"/animals/"), nhưng phần tử này 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 có 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ó đượ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 đây được chỉ định bằng "/**".
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 sau "/animals/"), nhưng phần tử này 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 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 có nhiều phần tử đứng sau "/animals"
Kết hợp dấu hoa thị
Bạn có thể kết hợp dấu hoa thị đơn (*) và dấu hoa thị kép (**) để tinh chỉnh thêm kết quả 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ả 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 các tài nguyên API. Tài nguyên API là một đoạn đườ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 hai 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ở đại diện liên kết với 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 một trong hai 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 số 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 tài nguyên trên phần phụ trợ của bạn. Về cơ bản, "Nếu có một lệnh gọi GET đến tài nguyên /reports, thì Edge sẽ làm 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 phần phụ trợ. Một là URL tài nguyên không được uỷ quyền, còn lại là proxy Edge API có luồng có điều kiện đến cùng một tài nguyên phụ trợ. Chúng tôi sẽ mô tả chi tiết hơn về các 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ể
Khi một 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 điều gì đó" khi có cuộc gọi đến tài nguyên /reports hoặc /forecasts. Tại thời điểm này, bạn không cần cho Edge biết việc cần làm, mà chỉ cần cho biết rằng Edge nên theo dõi các lệnh gọi đến những tài nguyên đó. Bạn thực hiện việc này bằng các điều kiện. Trong proxy Edge API, bạn có thể tạo các luồng có điều kiện cho /reports và /forecasts. Để minh hoạ về mặt lý thuyết, XML proxy API sau đây cho thấy các đ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 có yêu cầu GET với /reports và /forecasts trong URL, Edge sẽ thực hiện bất cứ điều gì bạn (nhà phát triển API) yêu cầu, thông qua các chính sách mà bạn đính kèm vào các luồng đó.
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 XML proxy API sau đây, khi yêu cầu GET được gửi đến https://yourorg-test.apigee.net/mygreatweatherforecast/reports, Edge sẽ thực thi chính sách "XML-to-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. Các chính sách này rất hữu ích cho việc thực thi chính sách khi bất kỳ lệnh gọi nào được thực hiện đến một proxy API. Ví dụ: nếu muốn xác minh khoá API của ứng dụng trong 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>. Để biết thêm thông tin về luồng, hãy xem phần Định cấu hình luồng.
Tạo luồng có điều kiện cho tài nguyên phụ trợ
Việc xác định luồng có điều kiện cho tài nguyên phụ trợ trong proxy API là hoàn toàn không bắt buộc. Tuy nhiên, các luồng có điều kiện đó cho phép bạn áp dụng quy trình quản lý và giám sát chi tiết.
Bạn sẽ có thể:
- Áp dụng phương thức quản lý 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 tài nguyên /developers đến /apps của phần phụ trợ.
Để làm vậy, bạn cần thêm hai 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 Điều hướng trong trình chỉnh sửa proxy API, hãy nhấp vào biểu tượng + bên cạnh mặc định trong Điểm cuối proxy.
![]()
Trong cửa sổ "New Conditional Flow" (Luồng có điều kiện mới), bạn sẽ nhập các cấu hình chính sau:
- Tên quy trình công việc: 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 lệnh gọi được gửi đến proxy có /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 bao gồm việc thiết lập các mục sau:
- Tên quy trình: Ứ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 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 có /apps ở cuối URI và động từ POST.
Trong ngăn điều hướng, bạn sẽ thấy các quy trình mới cho Ứng dụng và Nhà phát triển.

Chọn một trong các luồng để xem cấu hình luồng có điều kiện trong chế độ xem mã của trình chỉnh sửa 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>
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 gửi đến. (Biến proxy.pathsuffix xác định URI của yêu cầu theo 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 thử nghiệm, yêu cầu sau:
http://{org_name}-test.apigee.net/{proxy_path}/appssẽ khiến điều kiện được đánh giá là đúng và quy trình này, cùng với mọi chính sách liên quan, sẽ được thực thi.
Điều kiện trong ví dụ sau đây sử dụng biểu thức chính quy Java để nhận dạng các lệnh gọi được thực hiện đến tài nguyên /apps có hoặc không có dấu gạch chéo ở 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.
Tạo mô hình 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ụ: API Dịch vụ dành cho nhà phát triển cung cấp một phương thức để liệt kê tất cả ứng dụng thuộc về một nhà phát triển. Đường dẫn URI là:
/developers/{developer_email}/appsBạn có thể có các tài nguyên mà trong đó một mã nhận dạng duy nhất được tạo cho mỗi thực thể trong một tập hợp, đôi khi được chú thích như sau:
/genus/:id/species
Đường dẫn này áp dụng tương đương cho hai URI sau:
/genus/18904/species /genus/17908/species
Để thể hiện cấu trúc này trong tài nguyên API, bạn có thể sử 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 thành tài nguyên API một cách thích 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 phân giải mọi thứ bên dưới một mảnh URI nhất định. Để làm 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. 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}/keysSau đây là giao diện của đ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ới 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 được đính kèm vào một 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>
Quy trình 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 điều kiện
Dưới đây là một số ví dụ về 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 = 500request.uri MatchesPath "/*/statuses/**"request.queryparam.q0 NotEquals 10
Ví dụ thực tế: Bỏ qua dấu "/" ở cuối đường dẫn
Nhà phát triển Edge thường muốn xử lý cả hai hậu tố đường dẫn này: "/cat" và "/cat/". Lý do là vì một số người dùng hoặc ứng dụng khách có thể gọi API của bạn bằng dấu gạch chéo bổ sung ở cuối đường dẫn và bạn cần có khả năng xử lý việc đó trong các câu lệnh có điều kiện. 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ể thực hiện việc này mà không cần sử dụng Biểu thức chính quy 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 phù hợp. Rõ ràng và dễ đọc.
Tuy nhiên, bạn có thể làm điều 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ông khớp hoặc khớp với một trong các ký tự trước đó. Do đó, cả "/cat" và "/cat/" đều khớ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 không hoặc chỉ một lần xuất hiện của ký tự đứng trước và không cho phép ký tự nào khác.
So khớp chuỗi tuỳ ý bằng JavaRegex
Trong tất cả ví dụ của chủ đề này, chúng tôi sẽ hướng dẫn 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 hoặc biến luồng tuỳ ý nào, cho dù đó có phải là biến luồng tích hợp sẵn như proxy.pathsuffix hay không.
Ví dụ: nếu có một điều kiện kiểm tra chuỗi tuỳ ý, có thể là chuỗi được trả về trong tải trọng phụ trợ hoặc chuỗi được trả về từ quá trình tra cứu máy chủ xác thực, thì bạn có thể sử dụng toán tử so khớp để kiểm tra chuỗi đó. 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 chủ thể là "abc" và biểu thức chính quy là "[a-z]", thì sẽ không có kết quả khớ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ề danh sách các vai trò dưới dạng một chuỗi được phân tách bằng dấu phẩy: "editor, author, guest".
Để 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ì "người chỉnh sửa" 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>
Cách này hiệu quả vì nó tính đến các dấu ngắt từ và mọi phần khác của chuỗi có tiền tố và hậu tố .*.
Trong ví dụ này, bạn cũng có thể kiểm tra "editor" bằng toán tử Matches:
<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 phù hợp 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 có biểu thức Regex chứa dấu ngoặc kép, bạn cần có một cách khác để so khớp chúng. 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"'
request.header.Content-Type ~~ "(multipart\/related)(; *type="application\/xop\+xml\")"
\u0022. Ví dụ: biểu thức sau đây là hợp lệ và tạo ra kết quả như mong đợi:
request.header.Content-Type ~~ "(multipart\/related)(; *type=\u0022application\/xop\+xml\u0022)"