- Status:
connected - Done:
to_jsonable()、ok()、ok_list()、fail()、Envelope/ListEnvelope、复杂类型序列化规则、streaming/binary response 与 envelope 的例外边界、复杂类型 golden examples 和 OpenAPI schema regression 已落地。 - Next: none
Serialization 模块负责统一 JSON 编码、模型导出、响应封装和特殊类型序列化。
Schema 是 API 契约,负责输入输出字段、校验和文档。
Serialization 是编码策略,负责把 Python 对象稳定地转成 JSON 可传输结构。
schemas.py
定义这个接口有哪些字段。
core.serialization
定义 datetime、Decimal、UUID、Enum、ORM model 如何输出。
两者关系是:schema 使用 serialization 策略,但 serialization 不替代 schema。
src/core/serialization/
encoders.py
responses.py
json.py
datetime使用 ISO 8601,必须带时区;naive datetime 在 API 输出前视为错误。- 默认存储和输出使用 UTC;如保留 offset,必须在 schema 中显式说明。
date使用YYYY-MM-DD。Decimal默认转字符串,避免精度丢失。UUID转字符串。Enum输出 value。- ORM model 不直接裸返回,必须经过 schema 或 serializer。
- Pydantic 输出统一使用
model_dump(mode="json", by_alias=True);项目内 Pydantic 对象必须继承core.base.Schema或其子类。 - 默认不使用
exclude_none=True影响 envelope 字段;envelope 未使用字段显式为null。
当前实现提供 to_jsonable(),并已接入 ok()、ok_list() 和 fail():
- aware
datetime输出isoformat(),naivedatetime抛SYSTEM_ERROR。 date、Decimal、UUID、Enum和嵌套 list/dict 会递归编码。- Pydantic model 先
model_dump(mode="python", by_alias=True),再经过统一编码。 - OpenAPI 响应模型使用
Envelope[T]和ListEnvelope[T]泛型绑定具体 payload schema;运行时仍通过ok()/ok_list()输出同一 envelope 字段。
序列化契约有两类固定 artifact:
docs/contracts/serialization/golden-examples.json:覆盖 awaredatetime、date、Decimal、UUID、Enum、Pydantic alias、tuple/list、嵌套对象和 envelope null 字段。docs/contracts/serialization/example-openapi-schema.json:固定 golden app 的 typedEnvelope[ExamplePing]、ListEnvelope[ExampleRead]、pagination schema 和 list query 参数。
tests/contract/test_serialization_regression.py 会把当前运行时输出和上述 artifact 对比。修改 serialization、Schema、response envelope、OpenAPI 生成或 golden app schema 时,必须先确认契约变更是有意的,再同步更新对应 artifact。
core.base.schemas.Schema 是项目内 Pydantic 契约根类,Schema、response envelope、配置子模型和 service DTO 都应继承它:
from_attributes = True
populate_by_name = True
arbitrary_types_allowed = True
统一响应 helpers 放在 serialization 或 response 模块中:
ok(data)
ok_list(items, pagination)
fail(code, message=None, details=None, status_code=None, headers=None)
- 业务 router 禁止直接返回裸 ORM model。
- 业务 router 禁止直接返回裸 dict/list。
- 所有 JSON 响应必须经过 response helper。
- router 应声明
response_model=Envelope[ReadSchema]或response_model=ListEnvelope[ReadSchema],避免 OpenAPI 退化为裸 object。 - 文件下载、流式响应不走 JSON envelope,route 必须显式声明
response_class=FileResponse或response_class=StreamingResponse;失败时仍走 JSON envelope。