A JSON API boundary validates content type, payload shape and domain values before performing application work.
Flask JSON API: reject unknown fields, booleans and oversized bodies
Operation contract
The receipt estimate requires exactly quantity and unit_minor, both bounded exact integers. bool is rejected even though it inherits from int. A 256-byte framework request limit is separate from schema validation. The successful view returns a calculated total only; it does not write a ledger or charge a payment method.
Failure and ownership boundary
The built-in JSON parser can already have collapsed duplicate object keys before this schema check. A wire contract that rejects duplicate keys needs a custom parser or an earlier strict ingestion boundary. Malformed JSON, unsupported media types and excessive bodies are HTTP errors, not valid empty requests. Python JSON validation: reject duplicate members and non-integer amounts explains the distinction.
Tested environment
Dependency check: this program was executed on CPython 3.14.6 with Flask==3.1.3. Install these versions in a separate virtual environment. The download includes the recorded environment snapshot; no third-party package is part of the website runtime.
Working program
from flask import Flask, abort, request
def create_application():
application = Flask(__name__)
application.config.update(TESTING=True, MAX_CONTENT_LENGTH=256)
@application.post("/receipt-estimates")
def estimate():
payload = request.get_json()
if type(payload) is not dict or set(payload) != {"quantity", "unit_minor"}:
abort(400)
quantity, unit_minor = payload["quantity"], payload["unit_minor"]
if type(quantity) is not int or type(unit_minor) is not int or not 0 <= quantity <= 100 or not 0 <= unit_minor <= 100000:
abort(400)
return {"total_minor": quantity * unit_minor}
return application
client = create_application().test_client()
print(client.post("/receipt-estimates", json={"quantity": 3, "unit_minor": 125}).get_json())
print(client.post("/receipt-estimates", json={"quantity": True, "unit_minor": 125}).status_code)
print(client.post("/receipt-estimates", json={"quantity": 1, "unit_minor": 1, "extra": 2}).status_code)
print(client.post("/receipt-estimates", data="x" * 300, content_type="application/json").status_code)Output
{'total_minor': 375}
400
400
413Costs and limits
Body parsing and schema checks scale with accepted bytes and fields. A byte limit should also be enforced at the deployment proxy; this local test proves only the configured application behavior.
Common Mistakes
- Exact int checks avoid accepting booleans as quantities.
- Framework-parsed dictionaries do not preserve evidence of duplicate JSON keys.
Connected lessons
Python JSON validation: reject duplicate members and non-integer amounts, Flask routing: application factories, converters and test clients, Python input exercise: accept an explicit integer grammar.
Follow the related contract
Flask SQLite application: own the request connection and verify a clean reopen.
Check the next state boundary
Flask error responses: preserve status without exposing internal exception text.
Follow the service contract
Python Flask multipart uploads: bound the body, part count and accepted file.
Follow the ownership and update boundary
Python Flask ETag responses: preserve cache validators across conditional reads.
