Batu Lab NotesPractical developer guides

Keep JSON decoding separate from domain validation

By Batu · English technical notes

Keep JSON decoding separate from domain validation: json.loads() can successfully turn {"count": -1} into a Python dictionary even though a domain model may forbid negative counts. A successful decode establishes valid JSON syntax and the JSON-to-Python conversion; it does not establish an application rule such as “count is non-negative.” The example prints the source and decoded dictionary before validation so that separation is visible.

validate_count owns the domain contract. It uses type(value) is int rather than isinstance(value, int), because JSON true becomes Python True and bool is an int subclass. A negative integer returns the stable application outcome negative_count. The assertions independently check the decoded value and the domain result, rather than treating one as proof of the other.

Returning a short error code is one interface choice. Another application may raise a custom exception or collect several errors, but the policy should remain outside JSON parsing so it can evolve without redefining JSON syntax. This example works on Python 3.8+; json.loads itself is available in older releases. It is a synthetic example, not evidence that every domain should use the same count rule.

AI assistance disclosure: this article was drafted with AI using a deterministic synthetic input.

Source: Python json documentation.

import json

text = '{"count": -1}'
decoded = json.loads(text)


def validate_count(document):
    value = document.get("count")
    if type(value) is not int:
        return "count_must_be_integer"
    if value < 0:
        return "negative_count"
    return "ok"


assert decoded == {"count": -1}
result = validate_count(decoded)
assert result == "negative_count"

print(text)
print(decoded)
print("loads succeeds")
print(f"domain validation returns {result}")
{"count": -1}
{'count': -1}
loads succeeds
domain validation returns negative_count