Skip to content

Commit 8056837

Browse files
authored
Merge pull request #522 from nanotaboada/docs/architecture-diagram
docs(readme): update architecture diagram and add explanatory text
2 parents 50c0feb + 502b256 commit 8056837

File tree

3 files changed

+88
-22
lines changed

3 files changed

+88
-22
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
name: Bug report
3+
about: Report a bug or unexpected behavior
4+
title: "[BUG]"
5+
labels: bug
6+
assignees: ''
7+
8+
---
9+
10+
## Description
11+
12+
A clear and concise description of what the bug is.
13+
14+
## Steps to Reproduce
15+
16+
1. Step 1
17+
2. Step 2
18+
3. Step 3
19+
20+
## Expected Behavior
21+
22+
What you expected to happen.
23+
24+
## Actual Behavior
25+
26+
What actually happened.
27+
28+
## Environment
29+
30+
- **Python version:** (output of `python --version`)
31+
- **FastAPI version:** (from `pyproject.toml`)
32+
- **OS:** (e.g., macOS 14.0, Ubuntu 22.04, Windows 11)
33+
34+
## Additional Context
35+
36+
Add any other context about the problem here (logs, screenshots, etc.).
37+
38+
## Possible Solution
39+
40+
(Optional) Suggest a fix or workaround if you have one.

.github/copilot-instructions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,5 @@ Example: `feat(api): add player stats endpoint (#42)`
130130
feat(scope): description (#issue)
131131
132132
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
133+
Co-authored-by: Claude <noreply@anthropic.com>
133134
```

README.md

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -86,68 +86,93 @@ Proof of Concept for a RESTful API built with [Python 3](https://www.python.org/
8686

8787
## Architecture
8888

89+
Layered architecture with dependency injection via FastAPI's `Depends()` mechanism and Pydantic for request/response validation.
90+
8991
```mermaid
9092
%%{init: {
9193
"theme": "default",
9294
"themeVariables": {
9395
"fontFamily": "Fira Code, Consolas, monospace",
9496
"textColor": "#555",
95-
"lineColor": "#555",
96-
"lineWidth": 2
97+
"lineColor": "#555"
9798
}
9899
}}%%
99100
100-
graph BT
101-
%% Core application packages
101+
graph RL
102+
103+
tests[tests]
104+
102105
main[main]
103106
routes[routes]
107+
fastapi[FastAPI]
108+
aiocache[aiocache]
109+
104110
services[services]
105-
schemas[schemas]
106-
databases[databases]
111+
107112
models[models]
113+
pydantic[Pydantic]
108114
109-
%% External dependencies
110-
fastapi[FastAPI]
115+
schemas[schemas]
116+
117+
databases[databases]
111118
sqlalchemy[SQLAlchemy]
112-
pydantic[Pydantic]
113119
114-
%% Test coverage
115-
tests[tests]
120+
%% Strong dependencies
116121
117-
%% Module dependencies
118122
routes --> main
119123
fastapi --> main
124+
125+
fastapi --> routes
126+
aiocache --> routes
120127
services --> routes
121128
models --> routes
122129
databases --> routes
130+
123131
schemas --> services
124132
models --> services
125-
databases --> schemas
126-
fastapi --> routes
127-
sqlalchemy --> routes
128133
sqlalchemy --> services
134+
pydantic --> models
135+
136+
databases --> schemas
129137
sqlalchemy --> schemas
130138
sqlalchemy --> databases
131-
pydantic --> models
139+
140+
%% Soft dependencies
141+
142+
sqlalchemy -.-> routes
132143
main -.-> tests
133144
134-
%% Node styling
145+
%% Node styling with stroke-width
135146
classDef core fill:#b3d9ff,stroke:#6db1ff,stroke-width:2px,color:#555,font-family:monospace;
136147
classDef deps fill:#ffcccc,stroke:#ff8f8f,stroke-width:2px,color:#555,font-family:monospace;
137148
classDef test fill:#ccffcc,stroke:#53c45e,stroke-width:2px,color:#555,font-family:monospace;
138149
139150
class main,routes,services,schemas,databases,models core
140-
class fastapi,sqlalchemy,pydantic deps
151+
class fastapi,sqlalchemy,pydantic,aiocache deps
141152
class tests test
142153
```
143154

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.
145170

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.
147172

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
149174

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.
151176

152177
## API Reference
153178

0 commit comments

Comments
 (0)