mongodb driver via MongoModule / MongoService—Nest-style bootstrap only (no Mongoose runtime).
Full chapter: Recipe B in backend-recipes.md.
Dependencies
Bootstrap
Docker (local)
Typed document with _id (CRUD reads)
REST CRUD surface (example)
| Method | Path | Notes |
|---|---|---|
GET | /v1/profiles/ | List + optional skip query |
GET | /v1/profiles/:id | ObjectId parse → find_one |
POST | /v1/profiles/ | insert_one |
PUT | /v1/profiles/ | replace_one upsert by email |
PATCH | /v1/profiles/:id | find_one_and_update + $set |
DELETE | /v1/profiles/:id | delete_one by _id |
Unique email index (startup)
UseIndexModel + IndexOptions::builder().unique(true) once after MongoModule::for_root—see Recipe B § B.10 in the mdBook chapter.
Production MongoDB CRUD
Document APIs in production usually add tenant isolation, indexes that match queries, and honest partial updates.End-to-end example: customer profiles API
This shape is common for B2B SaaS admin APIs where support agents need fast reads, partial updates, and soft failure handling around duplicate emails.tenant_id + email and a list index on tenant_id + updated_at desc. That covers the two most common production queries: “find by email” and “show recent profiles.”
Multi-tenant documents
Modeltenant_id (or org_id) on every document you query by scope. Create a compound unique index on (tenant_id, email) instead of globally unique email when the same email may exist under different tenants.
Queries that scale
ForGET /profiles, use find with projection to avoid shipping large blobs, limit + skip (or cursor _id-based paging for deep offsets), and hint only when you have verified explain("executionStats") on staging.
Writes under contention
Usefind_one_and_update with ReturnDocument::After when you need compare-and-set semantics (for example incrementing version). For multiple collections that must commit together (transfer between accounts), use a MongoDB transaction (Client::start_session + multi-doc updates)—keep transactions short.
Replica sets and resilience
PointMONGODB_URI at the replica-set connection string (mongodb+srv://… on Atlas). Prefer retryable reads/writes for transient network errors; map WriteError categories to 409 (duplicate), 404 (filter matched nothing), 503 (not master / stepdown).
Observability
Loginserted_id / matched_count at debug level; emit metrics for mongodb_operation_duration_seconds per operation name (profiles.insert_one, …).
Prisma CLI can target Mongo for schema tooling; Rust reads/writes still go through
mongodb + BSON unless you add another layer.