Route Matching
When a request arrives through a Virtual API, DataHarbor validates the request path against the path template you provided during enrollment. This determines whether the request is admissible and which governed object controls apply. HTTP sources support two Route Enforcement modes during enrollment:| Mode | Behavior |
|---|---|
Strict | Requests must stay within the enrolled route template. Requests that move outside that template are rejected before the upstream call. |
Permissive | DataHarbor forwards any request path to the configured backend, even when it falls outside the enrolled route template. |
Strict mode.
How it works
InStrict mode, every HTTP source has a path template set during enrollment. DataHarbor uses this template to:
- Gate admissibility — reject requests that fall outside the template’s route family
- Resolve the governed object — determine which object’s controls apply to the response
- Derive cardinality — detect whether the response is a collection or a single resource
Admissibility rules
A request target is admissible when:- the number of path segments does not exceed the template’s segment count
- every literal segment in the template matches the corresponding segment in the request (case-insensitive)
- parameter segments (
{param}) accept any value
Examples
Given the template/customers/{customerId}/orders/{orderId}:
| Request path | Admissible | Reason |
|---|---|---|
/customers | ✅ | Prefix of the template |
/customers/42 | ✅ | Matches literal + param |
/customers/42/orders | ✅ | Matches through orders literal |
/customers/42/orders/100 | ✅ | Full template match |
/customers/42/orders/100/items | ❌ | Exceeds template depth |
/users/42 | ❌ | users does not match customers |
/orders/100 | ❌ | orders does not match customers |
Governed object resolution
DataHarbor resolves the governed object as the deepest literal segment that the request matches. This determines which object’s controls apply along with any_default controls.
Given the template /properties/{propertyId}/inspections/{inspectionId}/issues/{issueId}:
| Request path | Governed object | Cardinality |
|---|---|---|
/properties | properties | Many (collection) |
/properties/42 | properties | One (single resource) |
/properties/42/inspections | inspections | Many |
/properties/42/inspections/7 | inspections | One |
/properties/42/inspections/7/issues | issues | Many |
/properties/42/inspections/7/issues/3 | issues | One |
_default controls plus the resolved object’s controls. A request to /properties/42/inspections/7 applies _default + inspections — not properties.
Supported template shapes
DataHarbor supports all valid path template shapes, not just the standard alternatingliteral/{param} pattern.
Standard REST hierarchy
The most common pattern. Each literal names a resource collection, each parameter identifies a specific resource.Non-alternating templates
Templates where literals appear consecutively or in non-standard positions.All-parameter templates
Templates with no literal segments. Requests are validated against segment count, but there is no governed object — only_default controls apply.
Empty template (passthrough)
When no path template is provided, DataHarbor operates in passthrough mode. Any request path is admissible and no governed object is resolved. Only_default controls apply.
This is useful for sources where you want DataHarbor to apply uniform controls without constraining the URL structure.
Permissive route enforcement is similar in spirit: DataHarbor does not reject off-template paths before forwarding them to the backend.
Cardinality
DataHarbor derives cardinality from the last matched segment position:- If the last segment matched a parameter slot →
One(single resource) - If the last segment matched a literal →
Many(collection)
Many.
What gets rejected
InStrict mode, any request that fails admissibility is rejected before the upstream call is made.
Common rejection reasons:
- request path has more segments than the template allows
- a literal segment in the request does not match the corresponding template literal
- the source has no callable graph (missing enrollment data)

