Skip to content

Required Field Validation — Complete Guide

DodaTech Updated 2026-06-28 5 min read

In this tutorial, you'll learn about Required Field Validation. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

Required field validation ensures that mandatory fields are present and non-empty before processing a request.

What You'll Learn

By the end of this lesson, you will implement required field checks, handle edge cases like empty strings and whitespace, and implement conditional required fields.

Why It Matters

Missing required fields are the most common validation error. Proper required field handling prevents partial data, null reference errors, and inconsistent state.

Real-World Use

A payment API requires amount, currency, and source fields. Missing any one causes a 400 error before any charge is attempted.

Required Field Checker

# required_checker.py
from typing import Any, Dict, List, Optional

class RequiredChecker:
    @staticmethod
    def check(value: Any, field: str) -> Optional[str]:
        if value is None:
            return f"{field}: is required"

        if isinstance(value, str):
            if value.strip() == "":
                return f"{field}: cannot be empty"
            if value.strip() == "null" or value.strip() == "undefined":
                return f"{field}: invalid value"

        if isinstance(value, list) and len(value) == 0:
            return f"{field}: at least one item required"

        if isinstance(value, dict) and len(value) == 0:
            return f"{field}: cannot be empty object"

        return None

    @staticmethod
    def check_all(data: Dict, required_fields: List[str]) -> List[Dict]:
        errors = []
        for field in required_fields:
            error = RequiredChecker.check(data.get(field), field)
            if error:
                errors.append({"field": field, "message": error})
        return errors

checker = RequiredChecker()
tests = [
    ("name", None),
    ("name", ""),
    ("name", "  "),
    ("name", "Alice"),
    ("tags", []),
    ("tags", ["api"]),
    ("meta", {}),
]

for field, value in tests:
    err = checker.check(value, field)
    print(f"  field={field:8s} value={str(value):12s} -> {'VALID' if not err else err}")

Expected output:

  field=name     value=None         -> name: is required
  field=name     value=             -> name: cannot be empty
  field=name     value='  '         -> name: cannot be empty
  field=name     value='Alice'      -> VALID
  field=tags     value=[]           -> tags: at least one item required
  field=tags     value=['api']      -> VALID
  field=meta     value={}           -> meta: cannot be empty object

Conditional Required Fields

# conditional_required.py
from typing import Any, Dict, List, Optional

class ConditionalRequired:
    @staticmethod
    def if_present(field: str, depends_on: str, data: Dict) -> Optional[str]:
        if depends_on in data and data[depends_on] is not None:
            if field not in data or data[field] is None:
                return f"{field}: required when {depends_on} is provided"
        return None

    @staticmethod
    def if_value(field: str, condition_field: str, condition_value: Any,
                 data: Dict) -> Optional[str]:
        if data.get(condition_field) == condition_value:
            if field not in data or data[field] is None:
                return f"{field}: required when {condition_field} is {condition_value}"
        return None

    @staticmethod
    def one_of(group: List[str], data: Dict) -> Optional[str]:
        provided = [f for f in group if f in data and data[f] is not None]
        if len(provided) == 0:
            return f"At least one of {group} is required"
        if len(provided) > 1:
            return f"Only one of {group} is allowed, got {provided}"
        return None

cr = ConditionalRequired()
data = {"payment_method": "card"}
print(f"card_number required? {cr.if_value('card_number', 'payment_method', 'card', data)}")

data2 = {"payment_method": "card"}
print(f"One of (card, bank) required? {cr.one_of(['card_number', 'bank_account'], data2)}")

data3 = {"payment_method": "card", "card_number": "4111"}
print(f"Card number with card: {cr.if_value('card_number', 'payment_method', 'card', data3)}")

Expected output:

card_number required? card_number: required when payment_method is card
One of (card, bank) required? At least one of ['card_number', 'bank_account'] is required
Card number with card: None

Required Field Aggregator

# required_aggregator.py
from typing import Any, Dict, List

class RequiredFieldAggregator:
    def __init__(self):
        self.fields: List[str] = []
        self.conditional_rules: List[callable] = []

    def requires(self, *fields: str):
        self.fields.extend(fields)

    def requires_if(self, field: str, condition_fn: callable):
        self.conditional_rules.append((field, condition_fn))

    def validate(self, data: Dict) -> List[Dict]:
        errors = []

        for field in self.fields:
            value = data.get(field)
            if value is None or (isinstance(value, str) and value.strip() == ""):
                errors.append({"field": field, "code": "required"})

        for field, condition in self.conditional_rules:
            if condition(data) and (data.get(field) is None):
                errors.append({"field": field, "code": "required_conditional"})

        return errors

agg = RequiredFieldAggregator()
agg.requires("email", "password")
agg.requires_if("card_number", lambda d: d.get("payment") == "card")

print(agg.validate({"payment": "card"}))
print(agg.validate({"email": "a@x.com", "password": "123", "payment": "card", "card_number": "4111"}))

Expected output:

[{'field': 'email', 'code': 'required'}, {'field': 'password', 'code': 'required'}, {'field': 'card_number', 'code': 'required_conditional'}]
[]

Common Mistakes

1. Not Checking Empty Strings

Required fields with value "" pass is not None check. Always check for empty strings.

2. Not Trimming Before Check

A field with value " " is not empty but is effectively empty. Trim before checking.

3. Conditional Logic Too Complex

Deeply nested conditional requirements confuse clients. Flatten if possible.

4. Inconsistent Required Rules

Same field required in one endpoint, optional in another. Document endpoint-specific rules.

5. Required Read-Only Fields

Marking fields as required that the server calculates (like created_at) confuses clients.

Practice Questions

1. What values should a required field reject?

None, empty string, whitespace-only strings. Empty arrays and objects may also be rejected.

2. What is a conditional required field?

A field that is required only when another field has a specific value.

3. How do you implement one-of required groups?

Check that exactly one field from a group is present. Return error if zero or more than one.

4. Should you trim before required check?

Yes. A whitespace-only string is effectively empty. Trim and then check.

Challenge

Build a conditional required field system for a shipping form: address is required if shipping method is physical, digital_license is required if method is digital.

FAQ

Is an empty string a valid required field?

No. Required fields should have meaningful content. Reject empty strings.

How do I handle optional fields?

Mark them as optional. If provided, validate. If absent, skip.

What about default values?

If a field has a default, make it optional. Apply the default when absent.

Should arrays be required?

If the field is required, require at least one item. An empty array is not truly 'present'.

How do I communicate conditional requirements?

Document: 'card_number is required when payment_method is card'. Return clear error messages.

Mini Project: Required Field Manager

# required_mgr.py
from typing import Any, Dict, List

class RequiredManager:
    def __init__(self):
        self.required = set()

    def add(self, field: str):
        self.required.add(field)

    def check(self, data: Dict) -> List[str]:
        missing = []
        for field in self.required:
            if field not in data or data[field] is None or data[field] == "":
                missing.append(f"{field} required")
        return missing

mgr = RequiredManager()
mgr.add("username")
mgr.add("email")
print(mgr.check({"username": "alice"}))
print(mgr.check({"username": "alice", "email": "a@x.com"}))

Expected output:

['email required']
[]

What's Next

You understand required fields. Next, learn type checking, then format validation.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro