Skip to main content
Version: Next

Data Type Definition

Structured data in JSONClasses are defined with Python class syntax and type hint.

The Decorated Class#

Defining your data with JSONClasses is rather simple.

@jsonclassclass Cat:    name: str    birthday: date    weight: float

Declare a normal Python class, with magical @jsonclass decorator. There you get full power of JSONClasses.

tom = Cat(name='Tom', birthday='2020-08-31', weight=5.4)

Default Value#

You can specify default value on class definition.

@jsonclassclass Dog:    name: str    age: int    is_sold: bool = false    buyer_name: Optional[str]

Therefore, on object creation, a default value will be assigned if it's not provided.

buddy = Dog(name='Buddy', age=1)

Primitive Data Types#

JSONClasses supports str, int, float, bool, date and datetime.

@jsonclassclass MyObject:    str_value: str    int_value: int    float_value: float    bool_value: bool    date_value: date    datetime_value: datetime

Enum#

Enum is handy when defining a field with predictable limited amount of choices. Define enum in JSONClasses requires two steps just like in Python.

@jsonenumclass Sex(Enum):    MALE = 1    FEMALE = 2

@jsonclassclass Dog:    name: str    sex: Sex    age: int

To create an object with enum values, you can pass its capitalized name as value by default. You can tweak this behavior with types marker introduced in this guide.

buddy = Dog(name='Buddy', sex='MALE', age=1)

Collection Types#

JSONClasses supports collection types list and dict. You can nest them anyway you'd like.

@jsonclassclass MyObject:    list_value: list[str]    dict_value: dict[str, int]    nested_dict_in_list_value: list[dict[str, str]]    nested_list_in_dict_value: dict[str, list[int]]

Optional Type#

You can define optional type with Optional type annotation.

@jsonclassclass User:    username: str    email: str    invitation_code: Optional[str]

Embedded Object Types#

JSONClasses objects can have other JSONClasses objects as their field values.

@jsonclassclass ShippingAddress:    line1: str    line2: Optional[str]    city: str    country: str    postal_code: str

@jsonclassclass User:    username: str    shipping_addresses: list[ShippingAddress]

Linked Object Types#

On an object graph, objects are linked with each other. JSONClasses utilizes Python's Annotated type hint to declare link relationships right in type definitions.

@jsonclassclass Article:    title: str    content: str    author: Annotated[Author, linkto]

@jsonclassclass Author:    name: str    articles: Annotated[list[Article], linkedby('author')]

Link relationships are categorized into 3: 1-to-1, 1-to-many and many-to-many.

An 1-to-1 link relationship is declared with 1 side linkto and 1 side linkedby.

An 1-to-many link relationship is also declared with 1 side linkto and 1 side linkedby, while the declared type with linkedby is a JSONClasses object list of a specified class.

A many-to-many link relationship can be declared with 1 side linkto and 1 side linkedby. It can also be declared with double side linkedthru depends on how you persist your data in the database. The field type must be a JSONClasses object list type.

Types Modifiers#

A simple type hint won't satisfy complex data validation and transformation needs. This is where types modifier comes in.

We specify other types information with an unintuitive yet innovative equal sign.

@jsonclassclass User:    username: str = types.str.required    email: Optional[str] = types.str.email    password: str = types.writeonly.str.transform(salt).required    articles: list[Article] = types.listof('Article').linkedby('author').required    created_at: datetime = types.readonly.datetime.tscreated.required    updated_at: datetime = types.readonly.datetime.tsupdated.required

For a complete list of available types modifiers, please visit API Documentation: Types Modifiers.

ORM Integrated Models#

You can turn a existing JSONClasses class into ORM model definition by adding yet another magical decorator. These decorators are provided through additional packages.

@pymongo@jsonclassclass User:    id: str = types.readonly.str.primary.mongoid.required    email: Optional[str] = types.str.email    password: str = types.writeonly.str.transform(salt).required    articles: list[Article] = types.listof('Article').linkedby('author').required    created_at: datetime = types.readonly.datetime.tscreated.required    updated_at: datetime = types.readonly.datetime.tsupdated.required