Skip to main content
Goal: Official 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)

Unique email index (startup)

Use IndexModel + 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.
Pair this with a compound unique index on 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

Model tenant_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

For GET /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

Use find_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

Point MONGODB_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

Log inserted_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.