
从单体到微服务用FastAPI DDD思想构建可演进的目录架构当项目从初创阶段快速成长时技术债务往往成为制约发展的瓶颈。我曾参与过一个电商平台的重构项目最初采用传统分层架构的单体应用随着业务复杂度提升代码库逐渐变得难以维护。这正是我们需要探讨如何用领域驱动设计DDD思想规划FastAPI项目目录结构的意义所在。1. 领域驱动设计的核心概念与应用领域驱动设计DDD不是简单的目录结构调整而是一种思维方式转变。它要求开发者从业务领域出发而非技术实现角度来组织代码结构。1.1 战略设计与战术设计战略设计关注高层次的问题空间划分领域业务的核心知识领域如电商中的订单、支付、库存子域领域的细分部分如支付领域中的信用卡处理、退款管理限界上下文明确的语义边界决定模型适用范围战术设计则关注具体实现模式# 领域模型示例 class Order: def __init__(self, order_id: str, items: List[OrderItem]): self._id order_id # 领域标识 self._items items self._status OrderStatus.CREATED def add_item(self, product_id: str, quantity: int, price: Decimal): # 领域逻辑验证业务规则 if self._status ! OrderStatus.CREATED: raise DomainError(Cannot modify finalized order) self._items.append(OrderItem(product_id, quantity, price))1.2 识别领域模型的方法论在实践中我们使用事件风暴Event Storming工作坊来识别核心领域领域事件识别列出业务关键事件如订单已创建、支付已确认命令与聚合确定触发事件的操作和聚合根上下文映射绘制不同限界上下文间的交互关系提示初期可以先用简单文本描述领域模型不必追求完美设计随着业务理解深入逐步调整2. FastAPI与DDD的融合架构传统分层架构与领域驱动架构的关键区别在于组织维度。下面展示一个支持渐进式演进的混合架构方案2.1 过渡期目录结构设计your_project/ ├── core/ # 技术基础设施 ├── domains/ # 领域模块 │ ├── identity/ # 身份认证领域 │ │ ├── models.py │ │ ├── repository.py │ │ ├── services.py │ │ └── schemas.py │ └── ordering/ # 订单领域 │ ├── aggregates/ │ ├── events/ │ └── services/ ├── interfaces/ # 交付层 │ ├── rest/ # REST API │ └── events/ # 消息处理 └── infrastructure/ ├── db/ └── message_broker/这种结构特点纵向切割按业务领域组织代码横向分层保持技术实现与业务逻辑分离明确依赖领域层不依赖基础设施2.2 关键组件实现模式领域服务示例# domains/ordering/services.py class OrderService: def __init__(self, repo: OrderRepository, payment_gateway: PaymentGateway): self._repo repo self._payment payment_gateway async def place_order(self, cmd: CreateOrderCommand) - Order: async with self._repo.unit_of_work() as uow: order Order.create( user_idcmd.user_id, items[Item(i.product_id, i.quantity) for i in cmd.items] ) await self._payment.authorize(order.total_amount) await uow.orders.add(order) await uow.commit() return orderREST接口适配# interfaces/rest/v1/orders.py router.post(/orders, response_modelOrderResponse) async def create_order( request: CreateOrderRequest, service: OrderService Depends(get_order_service) ): try: order await service.place_order( CreateOrderCommand( user_idrequest.user_id, itemsrequest.items ) ) return OrderResponse.from_domain(order) except DomainError as e: raise HTTPException(400, detailstr(e))3. 渐进式拆分策略从单体到微服务的迁移应该是渐进过程而非一次性重写。以下是分阶段演进路径3.1 阶段划分与技术准备阶段架构特征技术准备风险控制模块化单体领域目录结构依赖注入容器接口兼容性垂直分解独立部署单元API网关数据一致性完全微服务独立数据存储服务网格分布式追踪3.2 解耦技术实现事件驱动架构示例# domains/ordering/events.py class OrderCreated(DomainEvent): order_id: str user_id: str total_amount: Decimal # infrastructure/message_broker/rabbitmq.py async def publish_event(event: DomainEvent): channel get_rabbitmq_channel() await channel.publish( exchangedomain_events, routing_keyevent.__class__.__name__, bodyevent.json() )依赖倒置实现# core/di.py def setup_dependency_injection(): container Container() container.register(OrderRepository, SQLOrderRepository) container.register(PaymentGateway, StripePaymentGateway) return container # 接口层使用 def get_order_service(repo: OrderRepository Depends()): return OrderService(repo)4. 实战中的架构决策点在实际项目中我们需要根据具体场景做出平衡决策4.1 共享内核与独立模型的权衡共享内核适用场景强一致性要求的领域如库存与订单高频交互的上下文早期开发阶段快速迭代独立模型适用场景明确限界上下文边界不同生命周期管理的领域准备拆分为独立服务的模块4.2 事务边界与一致性保障跨领域操作的一致性模式对比模式实现复杂度性能影响适用场景分布式事务高大金融交易等强一致性要求Saga模式中中业务流程较长的操作最终一致性低小可容忍短暂不一致的场景Saga实现示例class CreateOrderSaga: def __init__(self, steps: List[SagaStep]): self._steps steps async def execute(self): compensations [] try: for step in self._steps: await step.execute() compensations.append(step.compensate) except Exception: for compensate in reversed(compensations): await compensate() raise在项目初期采用合理的目录结构设计就像为建筑打下坚实的地基。当我们的电商平台用户量从1万增长到1000万时早期基于DDD的架构决策使得服务拆分变得水到渠成。记住好的架构不是一次性设计出来的而是在不断演进中自然形成的。