Skip to main content
BackAnt uses marshmallow for request body validation. Schemas live in api/schemas/ and are used in the service layer to validate incoming data before processing.

Schema structure

Each schema is a marshmallow Schema subclass. The naming convention is Post<Name>Schema for POST request schemas:
# api/schemas/PostUsers_schema.py
from marshmallow import fields, Schema

class PostUsersSchema(Schema):
    name = fields.String(required=True)
    email = fields.Email(required=True)
    age = fields.Integer(load_default=None)

Using a schema in a service

from marshmallow import ValidationError
from schemas.PostUsers_schema import PostUsersSchema
from helper.functions.validation_error import validation_error

class UsersService:
    def create_user(self, data):
        try:
            validated = PostUsersSchema().load(data or {})
        except ValidationError as e:
            raise validation_error(e)

        return self.users_repository.add_user(**validated)
validation_error() is a helper in api/helper/functions/validation_error.py that converts a marshmallow ValidationError into an APIException(400) automatically.

Common field types

FieldDescription
fields.String()String value
fields.Integer()Integer value
fields.Float()Float value
fields.Boolean()Boolean value
fields.Email()Validates email format
fields.URL()Validates URL format
fields.List(fields.String())List of strings
fields.Dict()Arbitrary dict
fields.DateTime()ISO 8601 datetime string

Field options

OptionDescription
required=TrueField must be present in input
load_default=valueDefault value when field is missing
allow_none=TrueAllow null values
validate=Attach a validator function

Validation example

from marshmallow import fields, Schema, validate

class PostProductSchema(Schema):
    name = fields.String(required=True, validate=validate.Length(min=1, max=100))
    price = fields.Float(required=True, validate=validate.Range(min=0))
    stock = fields.Integer(load_default=0)

Nested schemas

class AddressSchema(Schema):
    street = fields.String(required=True)
    city = fields.String(required=True)

class PostUserSchema(Schema):
    name = fields.String(required=True)
    address = fields.Nested(AddressSchema, required=True)

Error format

When validation fails, validation_error() raises APIException(400). The response body will be:
{"message": "Ocurrió un error"}
For more detailed validation error messages, inspect error.messages in the ValidationError and pass them to APIException:
except ValidationError as e:
    raise APIException(status_code=400, message=str(e.messages))