Skip to main content

Validation

Parameter validation is critical for security, data integrity, and API reliability. flAPI provides comprehensive validation that prevents SQL injection, enforces business rules, and generates automatic documentation.

Why Validation Matters

Without validation:

  • ❌ SQL injection attacks
  • ❌ Invalid data in database
  • ❌ Unexpected errors
  • ❌ Poor error messages

With validation:

  • ✅ SQL injection prevention
  • ✅ Data integrity guaranteed
  • ✅ Clear error messages
  • ✅ Automatic API documentation

Basic Validation

Add validators to any parameter:

request:
- field-name: customer_id
field-in: query
required: true
validators:
- type: int
min: 1
max: 999999

Validator Types

String Validator

For text input.

Basic String:

validators:
- type: string

With Constraints:

validators:
- type: string
min_length: 3
max_length: 50

Pattern Matching (Regex):

validators:
- type: string
pattern: '^[A-Za-z0-9_-]+$' # Alphanumeric, underscore, hyphen only

Enum (Whitelist):

validators:
- type: string
enum: ['active', 'inactive', 'pending']

Examples:

# Username
- field-name: username
validators:
- type: string
min_length: 3
max_length: 20
pattern: '^[a-zA-Z0-9_]+$'

# Email
- field-name: email
validators:
- type: string
pattern: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'

# Country Code
- field-name: country
validators:
- type: string
pattern: '^[A-Z]{2}$' # ISO 3166-1 alpha-2

# Status
- field-name: status
validators:
- type: string
enum: ['draft', 'published', 'archived']

Integer Validator

For whole numbers.

Basic Integer:

validators:
- type: int

With Range:

validators:
- type: int
min: 1
max: 100

Examples:

# Customer ID
- field-name: customer_id
validators:
- type: int
min: 1

# Page Number
- field-name: page
validators:
- type: int
min: 1
max: 1000

# Year
- field-name: year
validators:
- type: int
min: 1900
max: 2100

# Quantity
- field-name: quantity
validators:
- type: int
min: 1
max: 10000

Number Validator

For decimal numbers.

Basic Number:

validators:
- type: number

With Range:

validators:
- type: number
min: 0.0
max: 999999.99

Examples:

# Price
- field-name: price
validators:
- type: number
min: 0.01
max: 999999.99

# Latitude
- field-name: latitude
validators:
- type: number
min: -90.0
max: 90.0

# Longitude
- field-name: longitude
validators:
- type: number
min: -180.0
max: 180.0

# Discount Percentage
- field-name: discount
validators:
- type: number
min: 0.0
max: 100.0

Boolean Validator

For true/false values.

validators:
- type: boolean

Accepts:

  • true, false
  • 1, 0
  • "true", "false"
  • "yes", "no"

Examples:

# Active Status
- field-name: active
validators:
- type: boolean

# Include Details
- field-name: include_details
validators:
- type: boolean

# Is Admin
- field-name: is_admin
validators:
- type: boolean

Date Validator

For date strings.

validators:
- type: date
format: 'YYYY-MM-DD'

Examples:

# Date Range
- field-name: start_date
validators:
- type: date
format: 'YYYY-MM-DD'

- field-name: end_date
validators:
- type: date
format: 'YYYY-MM-DD'

# Birth Date
- field-name: birth_date
validators:
- type: date
format: 'YYYY-MM-DD'
max: 'today' # Can't be in the future

Array Validator

For multiple values.

validators:
- type: array
item_type: string
min_items: 1
max_items: 10

Examples:

# Category Filter
- field-name: categories
validators:
- type: array
item_type: string
enum: ['electronics', 'clothing', 'books']

# IDs
- field-name: product_ids
validators:
- type: array
item_type: int
min_items: 1
max_items: 100

Object Validator

For JSON objects (POST/PUT bodies).

validators:
- type: object
schema:
name:
type: string
required: true
email:
type: string
required: true
pattern: '^[^\s@]+@[^\s@]+\.[^\s@]+$'
age:
type: int
min: 18

Example:

# Create Customer
url-path: /customers/
methods: ['POST']
request:
- field-name: customer
field-in: body
required: true
validators:
- type: object
schema:
name:
type: string
required: true
min_length: 2
max_length: 100
email:
type: string
required: true
pattern: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
phone:
type: string
required: false
pattern: '^\+?[1-9]\d{1,14}$'
segment:
type: string
required: true
enum: ['AUTOMOTIVE', 'BUILDING', 'FURNITURE']

Multiple Validators

Combine validators for complex validation:

- field-name: username
validators:
- type: string
min_length: 3
max_length: 20
- type: string
pattern: '^[a-zA-Z0-9_]+$'

All validators must pass for the parameter to be valid.

Common Validation Patterns

Email Validation

- field-name: email
validators:
- type: string
pattern: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
max_length: 255

Phone Number Validation

# E.164 format
- field-name: phone
validators:
- type: string
pattern: '^\+?[1-9]\d{1,14}$'

URL Validation

- field-name: website
validators:
- type: string
pattern: '^https?://[^\s/$.?#].[^\s]*$'
max_length: 2048

UUID Validation

- field-name: request_id
validators:
- type: string
pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$'

Credit Card Validation

- field-name: card_number
validators:
- type: string
pattern: '^[0-9]{13,19}$'

Postal Code Validation

# US ZIP code
- field-name: zip_code
validators:
- type: string
pattern: '^\d{5}(-\d{4})?$'

# UK Postcode
- field-name: postcode
validators:
- type: string
pattern: '^[A-Z]{1,2}[0-9][A-Z0-9]? ?[0-9][A-Z]{2}$'

Error Messages

Default Error Messages

flAPI provides clear error messages:

# Missing required parameter
curl http://localhost:8080/customers/

{
"error": "Missing required parameter: customer_id",
"status": 400
}

# Invalid type
curl "http://localhost:8080/customers/?id=abc"

{
"error": "Parameter 'id' must be an integer",
"status": 400
}

# Out of range
curl "http://localhost:8080/customers/?age=150"

{
"error": "Parameter 'age' must be between 0 and 120",
"status": 400
}

# Invalid enum value
curl "http://localhost:8080/customers/?status=unknown"

{
"error": "Parameter 'status' must be one of: active, inactive, pending",
"status": 400
}

Custom Error Messages

Provide custom error messages:

validators:
- type: string
enum: ['AUTOMOTIVE', 'BUILDING', 'FURNITURE']
error_message: "Invalid segment. Please use AUTOMOTIVE, BUILDING, or FURNITURE"

Security Best Practices

1. Always Validate User Input

# ✅ Good: Validated
- field-name: status
validators:
- type: string
enum: ['active', 'inactive']

# ❌ Bad: No validation (SQL injection risk)
- field-name: status

2. Use Whitelists (Enums)

# ✅ Good: Whitelist of allowed values
validators:
- type: string
enum: ['name', 'email', 'created_at']

# ❌ Bad: Any string allowed
validators:
- type: string

3. Limit String Length

# ✅ Good: Prevent long strings
validators:
- type: string
max_length: 100

# ❌ Bad: Unlimited length
validators:
- type: string

4. Restrict Numeric Ranges

# ✅ Good: Reasonable limits
validators:
- type: int
min: 1
max: 1000

# ❌ Bad: No limits
validators:
- type: int

5. Use Strong Patterns

# ✅ Good: Strict pattern
validators:
- type: string
pattern: '^[A-Z]{2}$' # Exactly 2 uppercase letters

# ❌ Bad: Weak pattern
validators:
- type: string
pattern: '.*' # Matches anything

Testing Validation

Test Valid Input

$ curl "http://localhost:8080/customers/?segment=AUTOMOTIVE"

{
"data": [...]
}

Test Invalid Input

# Invalid enum
$ curl "http://localhost:8080/customers/?segment=INVALID"

{
"error": "Parameter 'segment' must be one of: AUTOMOTIVE, BUILDING, FURNITURE",
"status": 400
}

# Invalid type
$ curl "http://localhost:8080/customers/?id=abc"

{
"error": "Parameter 'id' must be an integer",
"status": 400
}

# Missing required
$ curl "http://localhost:8080/customers/"

{
"error": "Missing required parameter: segment",
"status": 400
}

Validate Configuration

$ flapii endpoints validate /customers/

✓ Validation configured correctly
• segment: string enum (AUTOMOTIVE, BUILDING, FURNITURE)
• id: integer (min: 1)
• active: boolean

Real-World Examples

Example 1: Product Search API

url-path: /products/search/
request:
- field-name: query
field-in: query
description: Search term
required: true
validators:
- type: string
min_length: 3
max_length: 100

- field-name: category
field-in: query
required: false
validators:
- type: string
enum: ['electronics', 'clothing', 'books', 'home']

- field-name: min_price
field-in: query
required: false
validators:
- type: number
min: 0
max: 999999.99

- field-name: max_price
field-in: query
required: false
validators:
- type: number
min: 0
max: 999999.99

- field-name: in_stock
field-in: query
required: false
validators:
- type: boolean

- field-name: limit
field-in: query
required: false
validators:
- type: int
min: 1
max: 100

Example 2: Order Creation API

url-path: /orders/
methods: ['POST']
request:
- field-name: order
field-in: body
required: true
validators:
- type: object
schema:
customer_id:
type: int
required: true
min: 1
items:
type: array
required: true
min_items: 1
max_items: 50
item_schema:
product_id:
type: int
required: true
quantity:
type: int
required: true
min: 1
max: 1000
price:
type: number
required: true
min: 0.01
shipping_address:
type: object
required: true
schema:
street:
type: string
required: true
city:
type: string
required: true
postal_code:
type: string
required: true
pattern: '^\d{5}(-\d{4})?$'
country:
type: string
required: true
pattern: '^[A-Z]{2}$'

Example 3: Date Range Analytics

url-path: /analytics/revenue/
request:
- field-name: start_date
field-in: query
description: Start date (YYYY-MM-DD)
required: true
validators:
- type: string
pattern: '^\d{4}-\d{2}-\d{2}$'

- field-name: end_date
field-in: query
description: End date (YYYY-MM-DD)
required: true
validators:
- type: string
pattern: '^\d{4}-\d{2}-\d{2}$'

- field-name: granularity
field-in: query
description: Data aggregation level
required: false
validators:
- type: string
enum: ['day', 'week', 'month', 'quarter', 'year']

- field-name: regions
field-in: query
description: Comma-separated region codes
required: false
validators:
- type: array
item_type: string
pattern: '^[A-Z]{2}$'

Common Issues

Validation Not Working

Problem: Parameters not being validated

Check:

  1. Validators are properly indented in YAML
  2. Validator type is supported
  3. flAPI server restarted after config changes

Pattern Not Matching

Problem: Valid values being rejected

Check:

  1. Regex pattern is correct (use online regex tester)
  2. Pattern uses correct syntax (PCRE/JavaScript style)
  3. Test with: flapii endpoints validate /endpoint/

Enum Not Working

Problem: Valid enum values being rejected

Check:

  1. Values are exact matches (case-sensitive)
  2. Enum array is properly formatted
  3. No trailing spaces in enum values

Next Steps

🍪 Cookie Settings