# Starts With Checks if a string value starts with a specified prefix. ## Overview The `starts_with` condition evaluates whether a field's string value begins with a specified prefix. This is useful for matching URL paths, ID prefixes, namespace patterns, and other cases where the beginning of a string is significant. ## Use Cases - **URL Path Routing**: Route based on URL path prefixes - **ID Namespace Matching**: Match IDs with specific prefixes - **Environment Detection**: Identify environments by hostname prefixes - **Log Source Routing**: Route logs based on source prefixes ## Configuration | Setting | Type | Required | Description | | ------------------ | ------- | -------- | -------------------------------------------------------------------------------------------- | | `key` | string | Yes | The field path to check. Supports dot notation for nested fields. Use `*` to check all keys.| | `value` | string | Yes | The prefix to check for. | | `case_insensitive` | boolean | No | If `true`, performs case-insensitive comparison. | | `not` | boolean | No | If `true`, inverts the condition (matches if value does NOT start with prefix). | ## Examples ### URL Path Routing Route API requests: ```json { "type_id": "starts_with", "config": { "key": "path", "value": "/api/v2/" } } ``` **Matches:** ```json {"path": "/api/v2/users"} {"path": "/api/v2/orders/123"} {"path": "/api/v2/"} ``` **Does not match:** ```json {"path": "/api/v1/users"} {"path": "/web/dashboard"} {"path": "api/v2/users"} ``` ### ID Prefix Matching Match IDs with specific prefixes: ```json { "type_id": "starts_with", "config": { "key": "id", "value": "usr_" } } ``` **Matches:** ```json {"id": "usr_12345"} {"id": "usr_abc"} ``` **Does not match:** ```json {"id": "ord_12345"} {"id": "12345"} ``` ### Case-Insensitive Prefix Match protocols regardless of case: ```json { "type_id": "starts_with", "config": { "key": "url", "value": "https://", "case_insensitive": true } } ``` **Matches:** ```json {"url": "https://example.com"} {"url": "HTTPS://EXAMPLE.COM"} {"url": "Https://Example.com"} ``` ### Environment Detection Identify production hosts: ```json { "type_id": "starts_with", "config": { "key": "hostname", "value": "prod-" } } ``` **Matches:** ```json {"hostname": "prod-web-01"} {"hostname": "prod-api-east"} ``` **Does not match:** ```json {"hostname": "staging-web-01"} {"hostname": "dev-api"} ``` ### Exclusion Check Match records that do NOT start with a prefix: ```json { "type_id": "starts_with", "config": { "key": "path", "value": "/internal/", "not": true } } ``` **Matches:** ```json {"path": "/api/users"} {"path": "/public/assets"} ``` **Does not match:** ```json {"path": "/internal/admin"} {"path": "/internal/metrics"} ``` ### Nested Field Check Check prefixes in nested fields: ```json { "type_id": "starts_with", "config": { "key": "request.path", "value": "/admin/" } } ``` **Matches:** ```json {"request": {"path": "/admin/users"}} {"request": {"path": "/admin/settings"}} ``` ### Log Source Routing Route logs by source prefix: ```json { "type_id": "starts_with", "config": { "key": "source", "value": "aws." } } ``` **Matches:** ```json {"source": "aws.cloudwatch"} {"source": "aws.s3"} {"source": "aws.lambda"} ``` ## Common Patterns ### API Version Routing Route different API versions: **V2 API:** ```json { "type_id": "starts_with", "config": { "key": "path", "value": "/api/v2/" } } ``` **V1 API (legacy):** ```json { "type_id": "starts_with", "config": { "key": "path", "value": "/api/v1/" } } ``` ### Multiple Prefix Matching Route based on any of several prefixes: ```json { "operator": "or", "conditions": [ {"type_id": "starts_with", "config": {"key": "id", "value": "usr_"}}, {"type_id": "starts_with", "config": {"key": "id", "value": "org_"}}, {"type_id": "starts_with", "config": {"key": "id", "value": "team_"}} ] } ``` ### Public vs Internal Routes Separate public and internal traffic: **Public routes:** ```json { "operator": "or", "conditions": [ {"type_id": "starts_with", "config": {"key": "path", "value": "/api/"}}, {"type_id": "starts_with", "config": {"key": "path", "value": "/public/"}} ] } ``` **Internal routes:** ```json { "operator": "or", "conditions": [ {"type_id": "starts_with", "config": {"key": "path", "value": "/internal/"}}, {"type_id": "starts_with", "config": {"key": "path", "value": "/admin/"}} ] } ``` ### Exclude Static Assets Filter out static asset requests: ```json { "operator": "and", "conditions": [ {"type_id": "starts_with", "config": {"key": "path", "value": "/static/", "not": true}}, {"type_id": "starts_with", "config": {"key": "path", "value": "/assets/", "not": true}} ] } ``` ### Combined Prefix and Suffix Match both beginning and end: ```json { "operator": "and", "conditions": [ {"type_id": "starts_with", "config": {"key": "filename", "value": "report_"}}, {"type_id": "ends_with", "config": {"key": "filename", "value": ".pdf"}} ] } ``` **Matches:** ```json {"filename": "report_2024.pdf"} {"filename": "report_quarterly.pdf"} ``` ### Service Namespace Routing Route by service namespace: ```json { "operator": "and", "conditions": [ {"type_id": "starts_with", "config": {"key": "service", "value": "payment."}}, {"type_id": "equals", "config": {"key": "environment", "value": "production"}} ] } ``` ## Best Practices 1. **Include delimiters**: Include trailing slashes or dots (e.g., `/api/` not `/api`) to avoid partial matches. 2. **Use `case_insensitive` for URLs**: URLs may have inconsistent casing. 3. **Combine with `ends_with`**: For matching both prefix and suffix patterns. 4. **Consider URL encoding**: URL paths may contain encoded characters. 5. **Be specific**: Longer prefixes are more precise and reduce false matches. ## Type Handling - **Strings**: Direct prefix comparison - **Numbers**: Converted to strings first (e.g., `123` starts with `"1"`) - **Booleans**: Converted to "true" or "false" strings - **Arrays/Objects**: Not supported for direct comparison - **Missing fields**: Returns `false` (or `true` if `not` is set) ## Limitations - Simple prefix matching only (no patterns or wildcards) - Single prefix per condition (use `or` for multiple prefixes) - No support for matching multiple prefixes in one condition ## Troubleshooting **Not matching expected values:** - Check for leading whitespace or special characters - Verify case sensitivity settings - Ensure the full prefix is specified **Unexpected matches:** - The prefix might be too short - Add delimiters to make prefix more specific **Case sensitivity issues:** - Enable `case_insensitive` for user-generated content - URLs and paths may have mixed casing