適用於:所有 API 管理層級
上下文變數使 進階管線場景中政策片段間的資料共享成為可能。 適當的變數管理對於建立可靠且具備最佳效能的管線至關重要。 處理不當可能導致執行時錯誤、效能問題及不可預測的行為。
變數基本原理
上下文變數提供執行緒安全的資料共享,政策片段間可透過內建的「set-variable」政策來建立。 每個請求都維持其獨立的變數上下文,確保並行請求不會互相干擾。
變數生命週期管理
請求範圍:變數僅在單一請求期間存在,且在請求完成時自動進行垃圾回收。
階段持久性:在同一請求中,入站階段設定的變數在後端、出站及錯誤階段均可持續使用。
執行緒隔離:嚴格執行緒隔離確保每個請求在其獨立執行緒及其上下文物件上執行,防止跨請求資料干擾。
順序更新:任何片段都可以修改現有變數,後續片段會覆寫先前的值。 順序執行消除了鎖定機制的需求。
儲存閾值:平台優化小型集合的上下文變數管理,通常每個請求可包含 50 個變數或更少。
以片段形式設定與檢索變數
<!-- Example: Set a request-id context variable that is a required value for other fragments -->
<set-variable name="request-id" value="@{
var requestId = context.Request.Headers.GetValueOrDefault("X-Request-ID", "");
if (string.IsNullOrEmpty(requestId)) {
return Guid.NewGuid().ToString();
}
return requestId;
}" />
<!-- Example: Retrieve the same request-id context variable safely in another fragment -->
<set-header name="X-Correlation-ID" value="@{
return context.Variables.GetValueOrDefault<string>("request-id", "unknown");
}" />
最佳做法
使用安全變數存取
請務必對於可能的空值保持謹慎,使用GetValueOrDefault安全存取,並為所有變數存取提供有意義的預設值。
<!-- Safe access with default value -->
<set-variable name="log-level" value="@{
return context.Variables.GetValueOrDefault<string>("config-log-level", "INFO");
}" />
<!-- Safe string interpolation using GetValueOrDefault -->
<set-variable name="cache-key" value="@{
var userId = context.Variables.GetValueOrDefault<string>("auth-user-id", "anon");
var resource = context.Variables.GetValueOrDefault<string>("request-resource", "default");
return $"cache:{userId}:{resource}";
}" />
檢查變數存在
在存取前,確保由前置片段所產生的變數存在。 當缺少相依性時,請從兩種策略中選擇:
策略一: 快速失敗(關鍵依賴)
當缺少關鍵依賴時,回傳錯誤回應:
<choose>
<when condition="@(!context.Variables.ContainsKey("user-id"))">
<!-- Critical dependency missing - fail immediately -->
<return-response>
<set-status code="500" reason="Internal Server Error" />
<set-body>{"error": "Required variable missing", "missing_dependency": "user-id"}</set-body>
</return-response>
</when>
<otherwise>
<!-- Safe to proceed - use the user-id variable -->
<set-header name="X-User-ID" exists-action="override">
<value>@(context.Variables.GetValueOrDefault<string>("user-id", ""))</value>
</set-header>
</otherwise>
</choose>
策略二: 優雅處理(可選依賴)
當選擇性相依性遺失時,使用適當的回復行為繼續執行:
<choose>
<when condition="@(context.Variables.ContainsKey("user-id"))">
<!-- Optional variable available - use it -->
<set-header name="X-User-ID" exists-action="override">
<value>@(context.Variables.GetValueOrDefault<string>("user-id", ""))</value>
</set-header>
</when>
<otherwise>
<!-- Fallback to default when variable unavailable -->
<set-header name="X-User-ID" exists-action="override">
<value>unknown</value>
</set-header>
</otherwise>
</choose>
最小化變數存取
透過將多個存取合併為單一表達式,減少上下文變數查詢:
<!-- Good: Single consolidated access -->
<set-variable name="log-entry" value="@{
var level = context.Variables.GetValueOrDefault<string>("log-level", "INFO");
var requestId = context.Variables.GetValueOrDefault<string>("request-id", "unknown");
return $"[{level}] Request {requestId} completed";
}" />
<!-- Avoid: Multiple separate accesses -->
<set-variable name="level-prefix" value="@("[" + context.Variables.GetValueOrDefault<string>("log-level", "INFO") + "]")" />
<set-variable name="request-suffix" value="@("Request " + context.Variables.GetValueOrDefault<string>("request-id", "unknown") + " completed")" />
<set-variable name="log-entry" value="@(context.Variables.GetValueOrDefault<string>("level-prefix", "") + " " + context.Variables.GetValueOrDefault<string>("request-suffix", ""))" />
保持一致的類型
使用明確型別處理以達到最佳效能與可靠性。 在處理 政策表達式時,請用運算符指定預期型別 @() :
<!-- Set as boolean, use as boolean -->
<set-variable name="should-log-debug" value="@(true)" />
<choose>
<when condition="@(context.Variables.GetValueOrDefault<bool>("should-log-debug", false))">
<!-- Include detailed debug information in logs -->
</when>
</choose>
相關內容
- 建立包含政策片段的進階執行管線架構 ——設計模組化、可擴展政策片段架構的基礎模式,明確分離關注點。
- 政策片段中央元資料快取 ——針對跨片段共享元資料快取模式的實作指引。
- 政策注入與片段協調 - 片段注入模式與產品及 API 政策之間的協調。