全部產品
Search
文件中心

API Gateway:參數與條件運算式的使用

更新時間:Jul 13, 2024

本文講述API Gateway的參數以及條件運算式的使用。

1. 概述

在外掛程式中,支援使用者從當前的請求應答系統上下文中擷取參數,並使用自訂的條件運算式對參數進行判斷,本文描述參數的定義方法與條件運算式的書寫方法。

2. 參數的定義

2.1. 定義方式

在使用條件運算式前,需要先在parameters欄位中將所有需要在條件運算式中需要使用的參數進行顯式定義,參考下面的例子:

---
parameters:
  method: "Method"
  appId: "System:CaAppId"
  action: "Query:action"
  userId: "Token:UserId"

parameters欄位類型是字串類型的索引值對,keyvalue的定義規範為

  • key 表示在條件運算式中使用的變數名,變數名的規則為[a-zA-Z_][a-zA-Z0-9]+, 唯一

  • value 表示參數所在的位置,使用{location}{location}:{name}的方式進行定義,請參考如下的例子:

    • location 表示參數所在的位置,參考下一節的詳細描述

    • name 表示參數的名稱,用於在所在位置中定位參數,比如Query:q1表示請求的QueryString中名字為q1的第一個值

2.1. 參數的支援位置

在使用條件運算式前,我們需要先定義參與條件運算式計算的參數,目前API Gateway支援在外掛程式中直接使用如下位置的參數

位置名稱

適用範圍

說明

Method

請求

HTTP要求方法(大寫),如:

GET , POST

Path

請求

HTTP完整請求路徑,如:

/path/to/query

StatusCode

應答

後端的HTTP應答碼,如:

200 , 400

ErrorCode

應答

API Gateway系統錯誤碼

Header

請求/應答

使用 Header:{Name} 擷取名字為

{Name} 的HTTP頭的第一個值

Query

請求

使用 Query:{Name} 擷取QueryString中名字為 {Name} 的第一個值

Form

請求

使用 Form:{Name} 擷取請求Form中名字為 {Name} 的第一個值

Host

請求

使用 Host:{Name} 擷取匹配到的泛網域名稱模板參數

Parameter

請求

使用 Parameter:{Name} 擷取使用者API自訂參數中名字為 Name 的第一個值

BodyJsonField

應答*

使用BodyJson:{JPath}JSONPath 方式擷取請求/應答包體中的JSON欄位值

System

請求/應答

使用 System:{Name} 擷取名字為{Name} 的系統參數值

Token

請求/應答

當處於jwt外掛程式認證時,使用Token:{Name} 擷取token中名字為 {Name} 的值

XFF

請求

填寫格式為XFF:{index},index的值為X-Forwarded-For頭中IP排序序號,從0開始算,允許負數,比如X-Forwarded-For的值為IP1,IP2,IP3,那麼如果index值為0,取IP1,如果index的值為-1,取IP3,也就是倒數第一個IP

取值規則的說明

  • 參數存取控制外掛程式,流量控制外掛程式,後端路由外掛程式發生在要求階段,外掛程式僅支援適用範圍為請求的參數位置:Method,Path,Header,Query,Form,Parameter,System,Token,XFF

  • 錯誤碼映射外掛程式發生在應答階段,外掛程式僅支援適用範圍為應答的參數位置:StatusCode,ErrorCode,Header,BodyJsonField,System,Token

  • Method,Path,StatusCode,ErrorCodeXFF這幾個位置僅提供Location即可,不需要Name

  • Header位置的參數,當用於要求階段的外掛程式時,讀取來自用戶端請求中的Header; 當用於應答階段的外掛程式時,讀取來自後端應答中的Header

  • Parameter位置的參數,僅用於要求階段的外掛程式,尋找API定義中同名的參數,使用參數名而非後端參數名尋找,當參數不存在時返回為null

  • Host位置的參數,僅支援在泛網域名稱參數提取,參考使用自訂網域名調用API文檔的3.2章節, 完整的Host請使用System:CaDomain讀取系統參數

  • Path返回為完整的請求路徑,如果需要Path位置的參數,請使用Parameter位置的參數

  • BodyJsonField位置的參數,目前僅支援在錯誤碼映射外掛程式中使用,使用JSONPath方式讀取應答JSON包體的值,參考2.4. JSONPath使用說明

  • Token當配置了JWT認證外掛程式時,使用Token:{CliamName}可以讀取在外掛程式定義的值,參考對應外掛程式的文檔

2.3. JSONPath使用說明

用於BodyJsonField位置,目前僅用於錯誤碼映射外掛程式,用於從後端返回的json包體中提取json中的欄位,關於JSONPath的詳細規範說明,請參考JSONPath介紹文檔。

  • 例子:使用 code:"BodyJsonField:$.result_code" 可以從如下的包體中得到 result_code 的值,對於如下的包體,可以解析到 code : ok

{ "result_code": "ok", "message": ... }

2.4. 系統參數列表

參數名稱

參數含義

取值列表

CaClientIp

請求來源用戶端IP

如: 37.78.XX.XX ,fe80::1849:59fd:993c:fcff

CaDomain

請求的完整網域名稱(Host頭)

如:

example.aliyundoc.com

CaAppId

請求的 APP 的 ID

如:

49382332

CaAppKey*

請求的 APP 的 Key

如:

12983883923

CaRequestId

網關產生的唯一請求ID

如:

CCE4DEE6-26EF-46CB-B5EB-327A9FE20ED1

CaApiName

API 名稱

如:

TestAPI

CaHttpSchema

調用協議

取值範圍:http, https, ws

CaClientUa

用戶端的UserAgent頭

透傳用戶端上傳的值

CaCloudMarketInstanceId

雲市場購買關係ID

雲市場

CaMarketExpriencePlan

是否開通雲市場體驗計劃

開通:true

未開通:false

3. 條件運算式

條件運算式可在外掛程式或其他情境中使用,用於在需要的情境中執行靈活的條件判斷

3.1. 基本文法

  • 條件運算式與SQL運算式類似,比如:$A > 100 and '$B = 'B'

  • 運算式的基本為{參數} {操作符} {參數}格式,如:$A > 100參數支援變數參數常量參數

  • 變數參數$開頭,用於引用在上下文中定義好的參數,例如:parameters中定義了q1:"Query:q1"的參數,在運算式中可以使用變數$q1,這個變數的值為當前請求中名為q1的Query參數的值

  • 常量參數支援字串數字布爾類型,如"Hello",'foo',100,-1,0.1,true,請參考3.2. 參數類型與判斷規則

  • 支援以下操作符

  • =, ==:等於判斷

  • <>, !=:不等於判斷

  • >, >=, <, <=:比較判斷

  • like, !like:相似判斷,在字串頭尾的%可用於判斷字串相似,如$Query like 'Prefix%'

  • in_cidr, !in_cidr:判斷IP地址的掩碼,例如:$ClientIp in_cidr '47.89.XX.XX/24'

  • 可使用null來判斷參數是否為空白,如:$A == null$A != null

  • 可以使用and, or, xor來組合串連不同的運算式,預設串連順序為從右至左

  • 可以用小括弧()來指定條件的優先順序

  • 使用!(, )可以對括起來的運算式執行取反操作,如:!(1=1)結果為false

  • 系統內建了一些函數,用於一些特殊情境的判斷

    • Random(): 產生一個0-1的浮點型別參數,用於藍綠髮布等一些需要隨機的場合

    • Timestamp():返回以毫秒計數的Unix時間戳記

    • TimeOfDay():按GMT時區,返回目前時間到當日零點的毫秒數

3.2. 參數類型與判斷規則

  • 運算式中支援以下類型

    • STRING:字串類型,支援單引號或雙引號,如:"Hello", 'Hello'

    • NUMBER:整數或浮點數類型,如:1001-1, 0.1, -100.0

    • BOOLEAN:布爾類型,如:truefalse

  • 對於等於,不等於,比較操作符,不同類型的判斷依據為:

    • STRING:使用字串順序執行判斷,例如:

      • '123' > '1000' 結果為true

      • 'A123' > 'A120' 結果為true

      • '' < 'a' 結果為true

    • NUMBER:使用數字大小進行判斷

      • 123 > 1000 結果為false

      • 100.0 == 100 結果為true

    • BOOLEAN:布爾值的判斷依據為:true大於false

      • true == true 結果為true

      • false == false 結果為true

      • true > false 結果為true

  • 對於等於,不等於,比較操作符,如果左右兩側的參數類型不一致,參考以下的判斷依據:

    • STRING NUMBER: 如果左值能轉換為NUMBER類型,則按照數字大小判斷,否則按照字串大小判斷,例如:

      • '100' = 100.0 結果為true

      • '-100' > 0 結果為false

    • STRING BOOLEAN: 當左值能夠轉換為BOOLEAN類型時(忽略大小寫等於truefalse),按照BOOLEAN類型判斷,否則除了!=判斷外,其餘的判斷結果均為false,參考如下例子:

      • 'True' = true 結果為true

      • 'False' = false 結果為true

      • 'bad' = false 結果為false

      • 'bad' != false 結果為true,對於左值非truefalse的情境,除了!=操作符結果為true,其餘結果均為false

      • 'bad' != true 結果為true

      • '0' > false 結果為false

      • '0' <= false 結果為false

    • NUMBERBOOLEAN: 永遠返回false

  • null值可用於欄位是否為空白的判斷,對於等於,不等於,比較操作符,判斷依據為

    • 當參數$A為空白時,$A == null 結果為true,$A != null 結果為false

    • Null 字元串''不等於null時: '' == null 結果為false'' == ''結果為true

    • 當用於比較操作符時,任意一測值為null,則結果為false

  • like!like操作符,可用於字串首碼、尾碼、包含的判斷,判斷依據為

    • 運算式僅支援右值為STRING常量的寫法,如$Path like '/users/%'

    • 右值兩端的'%'字元可用於支援首碼、尾碼、與包含判斷,如

      • 首碼判斷 $Path like '/users/%', $Path !like '/admin/%'

      • 尾碼判斷 $q1 like '%search', $q1 !like '%.do',

      • 包含判斷 $ErrorCode like '%400%', $ErrorCode !like '%200%',

    • 當左值為非NUMBERBOOLEAN類型時,會轉換為STRING格式後執行判斷

    • 當左值為空白值null時,結果為false

  • in_cidr!in_cidr運算式,可用於IP位址區段掩碼的判斷,判斷依據為

    • 運算式僅支援右值為STRING常量且符合IPv4或IPv6 CIDR格式的寫法,如:

      • $ClientIP in_cidr '10.0.0.0/8'

      • $ClientIP !in_cidr '0:0:0:0:0:FFFF::/96'

    • 當左實值型別為STRING類型時,會作為IPv4地址後進行判斷

    • 當左實值型別為NUMBER,BOOLEAN或為空白時,結果為false

    • System:CaClientIp參數會返回用戶端的IP地址,一般使用這種方式執行判斷

4. 使用案例

  • 隨機5%的幾率:

Random() < 0.05
  • 判斷當前API請求的是測試環境:

parameters:
  stage: "System:CaStage"
$CaStage = 'TEST'
  • 自訂參數中的UserName是Admin且來源IP在47.47.XX.XX/24範圍內

parameters:
  UserName: "Token:UserName"
  ClientIp: "System:CaClientIp"
$UserName = 'Admin' and $CaClientIp in_cidr '47.47.XX.XX/24'
  • 當前請求的使用者ID是1001,1098,2011中的一個,且使用HTTPS協議請求

parameters:
  CaAppId: "System:CaAppId"
  HttpSchema: "System:CaHttpSchema"
$CaHttpScheme = 'HTTPS' and ($CaAppId = 1001 or $CaAppId = 1098 or $CaAppId = 2011)`
  • 當應答StatusCode=200,包體json包體存在result_code且不為ok

parameters:
  StatusCode: "StatusCode"
  ResultCode: "BodyJsonField:$.result_code"
$StatusCode = 200 and ($ResultCode <> null and $ResultCode <> 'ok')

5. 使用限制

  • 單個外掛程式中的參數定義個數不超過16

  • 單個運算式的字元數不超過512個字元

  • BodyJsonField對請求或應答包體的限制為16K Bytes, 超過限制後將不會生效