You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
classDef test fill:#ccffcc,stroke:#53c45e,stroke-width:2px,color:#555,font-family:monospace;
138
149
139
150
class main,routes,services,schemas,databases,models core
140
-
class fastapi,sqlalchemy,pydantic deps
151
+
class fastapi,sqlalchemy,pydantic,aiocache deps
141
152
class tests test
142
153
```
143
154
144
-
**Arrow Semantics:** Solid arrows represent import-time module dependencies — the arrow points from the dependency to the consumer. The dotted arrow to `tests` indicates the integration tests validate the full application stack as wired by `main`.
155
+
*Simplified, conceptual view — not all components or dependencies are shown.*
156
+
157
+
### Arrow Semantics
158
+
159
+
Arrows point from a dependency toward its consumer. Solid arrows (`-->`) denote **strong (functional) dependencies**: the consumer actively invokes behavior — registering route handlers, dispatching requests, executing async queries, or managing the database session. Dotted arrows (`-.->`) denote **soft (structural) dependencies**: the consumer only references types without invoking runtime behavior. This distinction follows UML's `«use»` dependency notation and classical coupling theory (Myers, 1978): strong arrows approximate *control or stamp coupling*, while soft arrows approximate *data coupling*, where only shared data structures cross the boundary.
160
+
161
+
### Composition Root Pattern
162
+
163
+
The `main` module acts as the composition root — it creates the FastAPI application instance, configures the lifespan handler, and registers all route modules via `app.include_router()`. Rather than explicit object construction, dependency injection is provided by FastAPI's built-in `Depends()` mechanism: `routes` declare their dependencies (e.g. `AsyncSession`) as function parameters and FastAPI resolves them at request time. This pattern enables dependency injection, improves testability, and ensures no other module bears responsibility for wiring or lifecycle management.
164
+
165
+
### Layered Architecture
166
+
167
+
The codebase is organized into four conceptual layers: Initialization (`main`), HTTP (`routes`), Business (`services`), and Data (`schemas`, `databases`).
168
+
169
+
Third-party dependencies are co-resident within the layer that consumes them: `FastAPI` and `aiocache` inside HTTP, and `SQLAlchemy` inside Data. `routes` holds a soft dependency on `SQLAlchemy` — `AsyncSession` is referenced only as a type annotation in `Depends()`, without any direct SQLAlchemy method calls at the route level.
145
170
146
-
**Composition Root Pattern:**The `main` module acts as the composition root — it imports `FastAPI`and the route modules, creates the app instance, and registers all routers. This pattern enables dependency injection via `Depends()`, improves testability, and maintains clear separation of concerns.
171
+
The `models` package is a **cross-cutting type concern** — it defines Pydantic request and response models consumed across multiple layers, without containing logic or behavior of its own. Dependencies always flow from consumers toward their lower-level types: each layer depends on (consumes) the layers below it, and no layer invokes behavior in a layer above it.
147
172
148
-
**Layered Architecture:** Each layer has a specific responsibility — routes handle HTTP mapping, validation, and in-memory caching, services contain business logic, schemas define the ORM model, and databases manage the async session.
173
+
### Color Coding
149
174
150
-
**Color Coding:**Core packages (blue) implement the application logic, external dependencies (red) are third-party frameworks and ORMs, and tests (green) ensure code quality.
175
+
Core packages (blue) implement the application logic, third-party dependencies (red) are community packages, and tests (green) ensure code quality.
0 commit comments