Validation and Control Flow
KDeps provides multiple mechanisms to control resource execution and validate inputs before processing. All of these live under the unified run.validations: block.
Overview
The validations: block handles:
methods/routes— Limit which requests trigger the resourceheaders/params— Whitelist accepted headers and parametersskip— Skip execution based on runtime conditions (OR logic)check/error— Validate inputs before execution (AND logic, returns error on failure)required/rules/expr— Validate request data structure
Skip Conditions
Skip conditions allow you to conditionally skip resource execution based on runtime values.
Basic Usage
apiVersion: kdeps.io/v1
kind: Resource
metadata:
actionId: conditionalResource
name: Conditional Resource
run:
validations:
skip:
- get('skip') == true
- get('mode') == 'dry-run'
chat:
model: llama3.2:1b
prompt: "{{ get('q') }}"How It Works
- If any condition evaluates to
true, the resource is skipped - Skipped resources don't execute and produce no output
- Dependencies are still resolved (other resources can still reference it)
- Use
get()to access any data source
Common Patterns
validations:
skip:
# Skip if flag is set
- get('skip') == true
# Skip if no query parameter
- get('q') == '' || get('q') == null
# Skip based on item value (in items iteration)
- get('current') == 'skip_this'
# Skip if previous resource failed
- get('previousResource') == nullPreflight Checks
Preflight checks validate inputs before resource execution begins. If any condition fails, execution is aborted with a custom error.
Basic Usage
apiVersion: kdeps.io/v1
kind: Resource
metadata:
actionId: validatedResource
name: Validated Resource
run:
validations:
check:
- get('q') != ''
- get('userId') != null
- len(get('q')) > 3
error:
code: 400
message: Query parameter 'q' is required and must be at least 3 characters
chat:
model: llama3.2:1b
prompt: "{{ get('q') }}"How It Works
- All
checkconditions must pass (AND logic) - If any condition fails, execution stops and the
erroris returned - Runs before any resource action executes
Check Expressions
validations:
check:
- get('q') != ''
- get('userId') != null
- typeof(get('age')) == 'number'
- get('age') >= 18
- len(get('email')) > 5
- get('email').includes('@')
- get('status') == 'active' || get('status') == 'pending'
- get('previousResource') != null
error:
code: 400
message: "Validation failed"Error Response
When a check validation fails:
{
"success": false,
"error": {
"code": 400,
"message": "Query parameter 'q' is required and must be at least 3 characters"
}
}Route and Method Restrictions
Limit which HTTP requests can trigger a resource.
Basic Usage
apiVersion: kdeps.io/v1
kind: Resource
metadata:
actionId: apiResource
name: API Resource
run:
validations:
methods: [GET, POST]
routes: [/api/v1/data, /api/v1/query]
chat:
model: llama3.2:1b
prompt: "{{ get('q') }}"How It Works
- Resource only executes if both conditions match
- If restrictions don't match, resource is skipped silently
- Empty arrays mean "allow all"
Method Restrictions
validations:
methods: [GET] # only GET
methods: [GET, POST] # GET and POST
# omit to allow all methodsRoute Restrictions
validations:
routes: [/api/v1/users] # single route
routes: [/api/v1/users, /api/v1/profiles] # multiple routes
# omit to allow all routesCombined Example
run:
validations:
methods: [POST]
routes:
- /api/v1/create
- /api/v1/update
chat:
model: llama3.2:1b
prompt: "Create: {{ get('data') }}"Input Validation
Validate the structure and content of request data using required, rules, and expr.
Basic Usage
apiVersion: kdeps.io/v1
kind: Resource
metadata:
actionId: validatedInput
name: Validated Input
run:
validations:
required:
- userId
- action
properties:
userId:
type: string
minLength: 1
action:
type: string
enum: [create, update, delete]
age:
type: number
minimum: 18
maximum: 120
chat:
model: llama3.2:1b
prompt: "{{ get('action') }} user {{ get('userId') }}"Validation Syntax
KDeps supports multiple syntaxes for field validation:
properties (map format)
validations:
required: [email, name]
properties:
email:
type: string
pattern: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
name:
type: string
minLength: 1rules (array format)
validations:
required: [email, name]
rules:
- field: email
type: string
pattern: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
- field: name
type: string
minLength: 1fields (alternative map format)
validations:
required: [email, name]
fields:
email:
type: string
name:
type: string
minLength: 1Validation Rules Reference
| Rule | Type | Description |
|---|---|---|
required | array | List of required fields |
properties / fields / rules | object/array | Field-specific validation rules |
type | string | string, number, integer, boolean, object, array, email, url, uuid, date |
minLength | number | Minimum string length |
maxLength | number | Maximum string length |
minimum / min | number | Minimum numeric value |
maximum / max | number | Maximum numeric value |
enum | array | Allowed values |
pattern | string | Regex pattern (for strings) |
minItems | number | Minimum array items |
maxItems | number | Maximum array items |
message | string | Custom error message for this field |
Custom Expression Rules
run:
validations:
required: [email, password, confirmPassword]
properties:
email:
type: string
pattern: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
password:
type: string
minLength: 8
confirmPassword:
type: string
expr:
- expr: get('password') == get('confirmPassword')
message: "Passwords do not match"
- expr: get('email').includes('@')
message: "Email must contain @ symbol"
chat:
model: llama3.2:1b
prompt: "Process user: {{ get('email') }}"Allowed Headers and Parameters
Restrict which headers and query parameters are allowed in requests.
Allowed Headers
run:
validations:
headers:
- Authorization
- Content-Type
- X-API-Key
chat:
model: llama3.2:1b
prompt: "{{ get('q') }}"Headers not in this list are inaccessible via get().
Allowed Parameters
run:
validations:
params:
- q
- userId
- action
chat:
model: llama3.2:1b
prompt: "{{ get('q') }}"Parameters not in this list are inaccessible via get().
Combined Example
run:
validations:
methods: [POST]
routes: [/api/v1/secure]
headers:
- Authorization
- Content-Type
params:
- action
chat:
model: llama3.2:1b
prompt: "Secure action: {{ get('action') }}"Execution Order
Request
↓ methods / routes → skip if no match
↓ headers / params → filter inaccessible keys
↓ skip conditions → skip if any true
↓ check + error → abort with error if any false
↓ required/rules/expr → abort with 422 if invalid
↓ Execute ResourceBest Practices
1. Use skip for Optional Logic
validations:
skip:
- get('enableCache') != true2. Validate Early with check
# Good: Catch errors before expensive operations
validations:
check:
- get('userId') != null
- get('apiKey') != ''
error:
code: 400
message: "userId and apiKey are required"3. Restrict Routes for Security
validations:
routes: [/api/v1/admin]
methods: [POST]4. Combine All Controls
run:
validations:
methods: [POST]
routes: [/api/v1/admin]
headers: [Authorization]
check:
- get('adminToken') != null
error:
code: 401
message: Admin token required
skip:
- get('dryRun') == true
chat:
model: llama3.2:1b
prompt: "Admin: {{ get('action') }}"Examples
Example 1: Conditional Processing
apiVersion: kdeps.io/v1
kind: Resource
metadata:
actionId: smartProcessor
name: Smart Processor
run:
validations:
skip:
- get('process') != true
check:
- get('data') != null
- len(get('data')) > 0
error:
code: 400
message: Data is required
python:
script: |
data = get('data')
return process(data)Example 2: Secure Endpoint
apiVersion: kdeps.io/v1
kind: Resource
metadata:
actionId: secureEndpoint
name: Secure Endpoint
run:
validations:
methods: [POST]
routes: [/api/v1/secure]
headers: [Authorization, Content-Type]
check:
- get('Authorization') != null
- get('Authorization').startsWith('Bearer ')
error:
code: 401
message: Valid authorization token required
chat:
model: llama3.2:1b
prompt: "Secure: {{ get('q') }}"Related Documentation
- Validation — Full
validations:block reference - Expressions — Expression syntax for conditions
- Resources Overview — Resource structure
- Unified API — Using
get()in validations - Workflow Configuration — Route configuration