Skip to content

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 resource
  • headers / params — Whitelist accepted headers and parameters
  • skip — 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

yaml
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

yaml
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') == null

Preflight Checks

Preflight checks validate inputs before resource execution begins. If any condition fails, execution is aborted with a custom error.

Basic Usage

yaml
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 check conditions must pass (AND logic)
  • If any condition fails, execution stops and the error is returned
  • Runs before any resource action executes

Check Expressions

yaml
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:

json
{
  "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

yaml
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

yaml
validations:
  methods: [GET]         # only GET
  methods: [GET, POST]   # GET and POST
  # omit to allow all methods

Route Restrictions

yaml
validations:
  routes: [/api/v1/users]                   # single route
  routes: [/api/v1/users, /api/v1/profiles] # multiple routes
  # omit to allow all routes

Combined Example

yaml
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

yaml
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)

yaml
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: 1

rules (array format)

yaml
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: 1

fields (alternative map format)

yaml
validations:
  required: [email, name]
  fields:
    email:
      type: string
    name:
      type: string
      minLength: 1

Validation Rules Reference

RuleTypeDescription
requiredarrayList of required fields
properties / fields / rulesobject/arrayField-specific validation rules
typestringstring, number, integer, boolean, object, array, email, url, uuid, date
minLengthnumberMinimum string length
maxLengthnumberMaximum string length
minimum / minnumberMinimum numeric value
maximum / maxnumberMaximum numeric value
enumarrayAllowed values
patternstringRegex pattern (for strings)
minItemsnumberMinimum array items
maxItemsnumberMaximum array items
messagestringCustom error message for this field

Custom Expression Rules

yaml
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

yaml
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

yaml
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

yaml
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 Resource

Best Practices

1. Use skip for Optional Logic

yaml
validations:
  skip:
    - get('enableCache') != true

2. Validate Early with check

yaml
# 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

yaml
validations:
  routes: [/api/v1/admin]
  methods: [POST]

4. Combine All Controls

yaml
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

yaml
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

yaml
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') }}"

Released under the Apache 2.0 License.