Routing Rules Configuration¶
Doc Version: 1.0.0 Last Updated: 2026-08-23 Git Commit: f8a2eebe Author: Lincoln
Overview¶
JAiRouter provides a rule engine (v2.8.5) that enables conditional routing rules configured via the Web console or YAML. Route requests flexibly by model name, request headers, client IP, and more — without writing code.
The rule engine evaluates on every request: rules are matched by priority (highest first) and the first hit takes effect. When no rule matches, the original routing logic runs unchanged — behavior is identical to a deployment without the rule engine.
Use Cases¶
| Scenario | Example |
|---|---|
| Canary release | Route 10% of traffic to a new model by client IP |
| Tenant/channel isolation | Route by x-tenant header to different instance groups |
| Source restriction | Internal IPs (CIDR) go to dedicated instances |
| Model name rewrite | Requests for gpt-4 actually route to claude-3 |
| Instance pinning | Pin certain requests to a specific instance |
| Adapter switching | Switch OpenAI/Ollama adapters by request header |
| Weighted split | Same request consistently hits the same rule (IP+model hash) |
Matching Semantics¶
Condition Combination¶
- AND within a rule: all conditions must match
- OR across rules: matched by
prioritydescending, first match wins
Rule Fields¶
| Field | Description |
|---|---|
id | Unique identifier (auto-generated UUID) |
name | Rule name (required) |
enabled | Enabled flag, default true; disabled rules are skipped |
priority | Priority, higher matches first (0-9999) |
conditions | Condition list (all must match) |
action | Action to execute when matched |
Condition Types (type)¶
| Type | Description | Example value |
|---|---|---|
MODEL_NAME | Request model name | gpt-4 |
SERVICE_TYPE | Service type (chat/embedding/rerank/tts/stt/imgGen/imgEdit) | chat |
HEADER | Request header (requires field = header name) | vllm |
CLIENT_IP | Client IP | 10.0.0.0/8 |
WEIGHT | Weighted split (0-100 percent) | 50 |
Operators (operator)¶
| Operator | Description | Applicable conditions |
|---|---|---|
EQUALS | Equal (case-insensitive) | All |
CONTAINS | Contains | MODEL_NAME/HEADER/CLIENT_IP |
STARTS_WITH | Prefix match | MODEL_NAME/HEADER/CLIENT_IP |
REGEX | Regex partial match (find semantics) | MODEL_NAME/HEADER |
CIDR_MATCH | CIDR match, e.g. 192.168.1.0/24 | CLIENT_IP only |
WEIGHT condition: stable hash of
(clientIp + "|" + modelName), hit whenhash % 100 < weight. The same (IP, model) request always yields the same result, suitable for percentage-based splits.weightcomes from the condition'sweightfield, falling back tovalue, then 50.
Action Types (action.type)¶
| Type | Description | Target field |
|---|---|---|
TARGET_MODEL | Rewrite model name and select instances by the new name | modelName |
TARGET_INSTANCE | Pin an instance (by instanceId or name) | instanceId |
TARGET_ADAPTER | Switch adapter by name (falls back to instance adapter if unregistered) | adapterName |
LB_STRATEGY | Override load balancing strategy | lbStrategy |
LB_STRATEGY values:
random/round-robin/least-connections/ip-hash/consistent-hash. Unknown strategies fall back to the configured one.
Web Console Configuration¶
- Log in to the JAiRouter admin console
- Click Configuration → Routing Rules in the left menu
Creating a Rule¶
Click 「New Rule」 and fill in the form:
| Field | Description |
|---|---|
| Name | Rule name |
| Priority | 0-9999, higher matches first |
| Conditions | Multiple rows: condition type → operator → value; HEADER adds a header-name input; WEIGHT uses a 0-100 number |
| Action | Select action type + target value (model name / instance ID / adapter name / LB strategy with contextual hints) |
Managing Rules¶
- Enable/Disable: the table switch takes effect immediately
- Priority: edit the rule to change priority (batch reorder via API)
- Edit/Delete: via the action column
Rule changes take effect immediately — no restart required.
YAML Configuration¶
Edit src/main/resources/config/router/rules.yml:
model:
rules:
- id: route-vllm-header
name: Route to vLLM adapter by header
enabled: true
priority: 100
conditions:
- type: HEADER
field: x-routing
operator: EQUALS
value: vllm
action:
type: TARGET_ADAPTER
adapter-name: vllm
- id: route-internal-ip
name: Pin internal IPs to dedicated instance
enabled: true
priority: 90
conditions:
- type: CLIENT_IP
operator: CIDR_MATCH
value: 10.0.0.0/8
action:
type: TARGET_INSTANCE
instance-id: internal-gpu-1
- id: route-model-rewrite
name: Rewrite gpt-4 to claude-3
enabled: true
priority: 80
conditions:
- type: MODEL_NAME
operator: EQUALS
value: gpt-4
action:
type: TARGET_MODEL
model-name: claude-3
Default is an empty list (
model.rules: []), i.e. no rules enabled. YAML rules merge with Web-created rules: for the same id, the persisted (Web) rule overrides YAML.
API Reference¶
Base path: /api/config/rules
| Endpoint | Method | Description |
|---|---|---|
/api/config/rules/list | GET | List all rules (priority descending) |
/api/config/rules/{id} | GET | Get a single rule |
/api/config/rules | POST | Create a rule (409 if id exists) |
/api/config/rules/{id} | PUT | Update a rule |
/api/config/rules/{id} | DELETE | Delete a rule |
/api/config/rules/{id}/enable | PUT | Enable a rule |
/api/config/rules/{id}/disable | PUT | Disable a rule |
/api/config/rules/priority | PUT | Batch update priorities [{id, priority}] |
Create Rule Example¶
curl -X POST http://localhost:8080/api/config/rules \
-H "Content-Type: application/json" \
-H "Jairouter_Token: your-admin-token" \
-d '{
"name": "Route to vLLM by header",
"priority": 100,
"enabled": true,
"conditions": [
{"type": "HEADER", "field": "x-routing", "operator": "EQUALS", "value": "vllm"}
],
"action": {"type": "TARGET_ADAPTER", "adapterName": "vllm"}
}'
Batch Priority Example¶
curl -X PUT http://localhost:8080/api/config/rules/priority \
-H "Content-Type: application/json" \
-H "Jairouter_Token: your-admin-token" \
-d '[{"id": "rule-id-1", "priority": 200}, {"id": "rule-id-2", "priority": 100}]'
Verification¶
- Use AI Playground → Chat Test to send requests and observe routing
- Check backend logs for
Selected adapter/ routing selection info - Or call
/v1/*APIs with/without the conditional header and compare routing
Notes¶
- Hot reload: rule changes take effect immediately, no restart needed
- Persistence: Web-created rules are stored in StoreManager (key=
rule_definitions) and restored on restart - Priority: rules with the same priority keep insertion order; semantics are "first match wins" — avoid overlapping rules
- Performance: keep the rule count under ~100; per-request evaluation cost is negligible
- TARGET_ADAPTER: if the specified adapter is not registered, it logs a warning and falls back to the instance-level adapter
- HEADER conditions: only apply to
/v1/*request paths (headers are used for matching only, not outbound forwarding)