Edge routes — implementation reference¶
Developer-oriented reference for the Gateway edge route layer (Sprint 1 foundation). For operator-facing route configuration, see Gateway API — Edge Route Configuration. For flow policies on routes, see Gateway flow policies.
Scope¶
Implemented capabilities:
- Edge route schema and validation (
EdgeRouteConfig) - Policy loader with TTL cache and last-known-good fallback
- Deterministic route matcher (
method + path, exact and{param}templates) - Gateway integration for alias endpoints (
GET|POST|... /v1/api/{public_path}) - Structured
edge.decisionlogs (allow/deny) for Loki + OTEL span attributes for Tempo
Route schema contract¶
The route contract is defined by EdgeRouteConfig in Gateway.
Top-level fields:
api_version(defaultmeshflows.io/v1alpha1)kind(defaultEdgeRouteConfig)metadata(optional dictionary)spec.routes(list of route entries)
Route entry fields:
id(required, unique)method(required, normalized to uppercase)path(required, must start with/; may include whole-segment params like{id})target.workflow(required)auth(optional, defaults applied)constraints(optional, defaults applied)rate_limit(optional)transform(optional)
Validation rules:
- Duplicate route
idis rejected. - Duplicate
(method, path)is rejected. - Missing
target.workflowis rejected. - Invalid path templates (partial-segment
{…}, duplicate param names) are rejected.
Policy loader lifecycle¶
Loader behavior (EdgeRoutePolicyLoader):
- Reads raw route config from configured source.
- Validates and parses config into typed model.
- Caches the parsed config for TTL (
EDGE_ROUTE_CACHE_TTL_SECONDS). - Supports explicit cache invalidation.
- On refresh failure, falls back to the last known good config if available.
Startup behavior:
- Gateway performs startup validation in non-required mode.
- Invalid startup config does not crash startup when no route is requested.
- Runtime route resolution returns
503if no valid config can be loaded.
Matcher semantics¶
Matcher behavior (EdgeRouteMatcher):
- Exact
method + pathmatch wins. - Otherwise whole-segment templates are matched (
/v1/api/products/{id}→/v1/api/products/10003). - Among templates, prefer more static segments, then fewer params, then route
id. - Method match is case-insensitive via uppercase normalization.
- Path match is case-sensitive.
- Matched params are exposed to Orchestrator as query keys and
X-Mesh-Property-*headers.
Gateway handler mapping:
/v1/api/{public_path}resolves route by incoming method and absolute path.- On hit: forwards to Orchestrator
POST /run/{workflow}. - On miss: returns
404and emitsedge.decisiondeny log.
Environment variables¶
Route loader:
EDGE_ROUTE_CONFIG_JSONEDGE_ROUTES_DIR(YAML files; see Gateway API)EDGE_ROUTE_CACHE_TTL_SECONDS
Gateway forwarding path:
ORCHESTRATOR_URLGATEWAY_MAX_XML_BYTES
Quickstart: add a new edge route¶
- Create or update route config with a unique route id and method/path pair.
- Set
target.workflowto the internal workflow name. - Load via
EDGE_ROUTES_DIRorEDGE_ROUTE_CONFIG_JSON. - Trigger cache refresh (or wait for TTL expiration).
- Validate with request tests.
Example config snippet:
{
"api_version": "meshflows.io/v1alpha1",
"kind": "EdgeRouteConfig",
"metadata": { "name": "public-routes" },
"spec": {
"routes": [
{
"id": "orders-create-v1",
"method": "POST",
"path": "/v1/api/orders/create",
"target": {
"workflow": "sales_order_create_internal"
}
}
]
}
}
Example request:
curl -s -X POST http://localhost:8080/v1/api/orders/create \
-H "Content-Type: application/json" \
-d '{"xml":"<order/>"}'
Expected behavior:
- Route match forwards to orchestrator workflow
sales_order_create_internal. - Unknown route under
/v1/api/*returns404.
Test coverage¶
engine/tests/test_gateway_edge_routes_schema.pyengine/tests/test_gateway_edge_policy_loader.pyengine/tests/test_gateway_edge_route_matcher.pyengine/tests/test_gateway_edge_route_integration.py
These tests validate schema constraints, loader fallback behavior, deterministic matching, and no-downstream-call behavior on deny paths.