docs: collect refreshed mongo-ops wiki site (API-correct overhaul, v0.1.5)

This commit is contained in:
2026-09-14 13:46:11 +05:30
parent bbd9863d23
commit f406aa2f21
24 changed files with 2880 additions and 1525 deletions

View File

@@ -388,6 +388,8 @@
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
@@ -420,6 +422,8 @@
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
@@ -428,9 +432,36 @@
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#library-overview" class="md-nav__link">
<a href="#architecture" class="md-nav__link">
<span class="md-ellipsis">
Library Overview
🏗️ Architecture
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#lifecycle-rules" class="md-nav__link">
<span class="md-ellipsis">
🔄 Lifecycle Rules
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#which-repository-should-you-use" class="md-nav__link">
<span class="md-ellipsis">
🧭 Which Repository Should You Use?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#read-next" class="md-nav__link">
<span class="md-ellipsis">
➡️ Read Next
</span>
</a>
@@ -501,7 +532,7 @@
<span class="md-ellipsis">
02 components
Core Components
</span>
@@ -998,18 +1029,125 @@
<h1>Overview</h1>
<h2 id="library-overview">Library Overview</h2>
<p><code>mongo-ops</code> is a modular MongoDB operations layer for FastAPI microservices. It provides:</p>
<ul>
<li>Async connection management</li>
<li>Base document models with auto-timestamps</li>
<li>Generic CRUD repository pattern</li>
<li>Transaction support</li>
<li>Model registration system</li>
</ul>
<h1 id="library-overview">Library Overview</h1>
<p><code>mongo-ops</code> gives FastAPI/microservice teams a small, opinionated toolkit for talking to MongoDB asynchronously. This page builds the mental model: what the layers are, in what order they must be wired up, and which repository to reach for.</p>
<hr />
<h2 id="architecture">🏗️ Architecture</h2>
<div class="language-text highlight"><span class="filename">Text Only</span><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a>┌───────────────────────────────────────────────────────────┐
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a>│ Application (FastAPI) │
<a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a>│ ┌─────────────┬───────────────┬───────────────┬─────────┐ │
<a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a>│ │ CachedBase │ Populating │ BaseRepository│ Raw │ │
<a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a>│ │ Repository │ Repository │ (CRUDMixin) │ Motor │ │
<a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a>│ └──────┬──────┴───────┬───────┴───────┬───────┴─────────┘ │
<a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a>│ │ │ │ │
<a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a>│ ┌──────┴──────┐ ┌────┴──────┐ ┌─────┴─────────────────┐ │
<a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a>│ │ Cache backend│ │ Population│ │ TransactionManager │ │
<a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a>│ │ memory/redis │ │ Engine │ │ (session helpers) │ │
<a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a>│ └──────┬──────┘ └────┬──────┘ └─────────┬─────────────┘ │
<a id="__codelineno-0-12" name="__codelineno-0-12" href="#__codelineno-0-12"></a>│ ┌──────┴──────────────────────────────────┴─────────────┐ │
<a id="__codelineno-0-13" name="__codelineno-0-13" href="#__codelineno-0-13"></a>│ │ ModelRegistry (models, indexes, cache lifecycle) │ │
<a id="__codelineno-0-14" name="__codelineno-0-14" href="#__codelineno-0-14"></a>│ └──────┬─────────────────────────────────────────────────┘ │
<a id="__codelineno-0-15" name="__codelineno-0-15" href="#__codelineno-0-15"></a>│ ┌──────┴─────────────────────────────────────────────────┐ │
<a id="__codelineno-0-16" name="__codelineno-0-16" href="#__codelineno-0-16"></a>│ │ MongoConnectionManager (Motor client + database) │ │
<a id="__codelineno-0-17" name="__codelineno-0-17" href="#__codelineno-0-17"></a>│ └──────────────────────────┬──────────────────────────────┘ │
<a id="__codelineno-0-18" name="__codelineno-0-18" href="#__codelineno-0-18"></a>└─────────────────────────────┼────────────────────────────────┘
<a id="__codelineno-0-19" name="__codelineno-0-19" href="#__codelineno-0-19"></a>
<a id="__codelineno-0-20" name="__codelineno-0-20" href="#__codelineno-0-20"></a> MongoDB (Motor / PyMongo)
</code></pre></div>
<p>The layers build on each other:</p>
<ol>
<li><strong>Connection</strong><code>MongoConnectionManager</code> owns the Motor client and active database.</li>
<li><strong>Models</strong><code>BaseDocument</code> (Pydantic v2) gives every document <code>id</code> (aliased <code>_id</code>) plus <code>created_at</code> / <code>updated_at</code>.</li>
<li><strong>CRUD</strong><code>CRUDMixin</code> / <code>BaseRepository</code> implement generic async CRUD against a collection.</li>
<li><strong>Startup</strong><code>ModelRegistry</code> centralizes model + index registration and cache lifecycle for multi-collection services.</li>
<li><strong>Advanced layers</strong> — caching and population compose <em>around</em> a repository:</li>
<li><code>CachedBaseRepository</code> wraps <code>BaseRepository</code> with a <code>CacheBackend</code>.</li>
<li><code>PopulatingRepository</code> wraps <code>BaseRepository</code> with a <code>PopulationEngine</code>.</li>
<li><strong>Transactions</strong><code>TransactionManager</code> runs a list of async operations atomically on a session.</li>
</ol>
<hr />
<h2 id="lifecycle-rules">🔄 Lifecycle Rules</h2>
<p><code>mongo-ops</code> has a strict startup order. Violating it raises fast, loud exceptions:</p>
<table>
<thead>
<tr>
<th>Step</th>
<th>Call</th>
<th>Why</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td><code>await MongoConnectionManager.connect(uri, db_name)</code></td>
<td>Without a connection, <code>get_database()</code>/<code>get_client()</code> raise <code>RuntimeError("Database not connected...")</code>.</td>
</tr>
<tr>
<td>2</td>
<td><code>await ModelRegistry.initialize_all()</code></td>
<td>Create registered indexes (idempotent via <code>create_index</code>).</td>
</tr>
<tr>
<td>3</td>
<td><code>await ModelRegistry.set_cache_backend(...)</code> then <code>await ModelRegistry.initialize_cache()</code></td>
<td>Must happen <strong>after</strong> connection, <strong>before</strong> any cache-backed operation. Raises <code>RuntimeError("No cache backend registered...")</code> if skipped.</td>
</tr>
<tr>
<td>4</td>
<td>Use repositories</td>
<td>Constructed repos resolve the collection from the live database.</td>
</tr>
<tr>
<td>5</td>
<td><code>await ModelRegistry.shutdown_cache()</code> + <code>await MongoConnectionManager.disconnect()</code></td>
<td>On shutdown (in-memory TTL task cancelled; Redis pub/sub closed).</td>
</tr>
</tbody>
</table>
<p>The canonical wiring is the FastAPI <strong>lifespan</strong> context manager (see <a href="../03_use_cases/01_basic_crud/">use case 01</a>).</p>
<hr />
<h2 id="which-repository-should-you-use">🧭 Which Repository Should You Use?</h2>
<table>
<thead>
<tr>
<th>Repository</th>
<th>Use when</th>
<th>Adds</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>BaseRepository[T]</code></td>
<td>Plain CRUD — the default</td>
<td>nothing extra</td>
</tr>
<tr>
<td><code>CachedBaseRepository[T]</code></td>
<td>Readheavy, lowwrite fields (lookups by <code>_id</code>)</td>
<td>cachefirst <code>get_by_id</code>, cache on <code>create</code>, invalidate on <code>update</code>/<code>delete</code>, <code>warm_cache</code></td>
</tr>
<tr>
<td><code>PopulatingRepository[T]</code></td>
<td>You return related docs (FK references) denormalized</td>
<td><code>_populate</code> on read, <code>_depopulate</code> on write, FKguarded <code>patch</code></td>
</tr>
<tr>
<td><code>CRUDMixin</code></td>
<td>Reusing CRUD inside an existing class</td>
<td>raw CRUD against a collection you already have</td>
</tr>
</tbody>
</table>
<blockquote>
<p>There is <strong>no builtin <code>CachedPopulatingRepository</code></strong>. <a href="../03_use_cases/10_cache_and_population/">Use case 10</a> shows how to compose caching + population in a small subclass.</p>
</blockquote>
<hr />
<h2 id="read-next">➡️ Read Next</h2>
<ul>
<li><a href="../02_components/">Core Components</a> — the validated public API surface.</li>
<li><a href="../03_use_cases/01_basic_crud/">Use case 01</a> — the minimal FastAPI app.</li>
<li><a href="../04_best_practices/">Best Practices</a> — team-wide conventions.</li>
</ul>