Overview
The Catalog service uses Marten as its data persistence layer. Marten is a .NET library that provides document database capabilities using PostgreSQL as the backing store.Why Marten?
Document Database
Store .NET objects as JSON documents without ORM impedance mismatch
PostgreSQL Power
Leverage PostgreSQL’s JSONB storage and querying capabilities
LINQ Support
Write queries using familiar LINQ syntax
Event Sourcing
Built-in support for event sourcing patterns (not used in Catalog)
Configuration
Service Registration
Marten is configured inProgram.cs:
Program.cs
Connection String
Configure the database connection inappsettings.json:
appsettings.json
appsettings.json
Lightweight Sessions
The service uses lightweight sessions for better performance:- No identity map caching
- No automatic dirty checking
- Better performance for stateless HTTP APIs
- Lower memory footprint
Document Store
Product Document
Products are stored as JSON documents in PostgreSQL:Models/Product.cs
Storage Format
Marten stores this as a JSONB document in PostgreSQL:Database Schema
Marten automatically creates the necessary tables:Data Operations
Creating Documents
Products/CreateProduct/CreateProductHandler.cs
Store()adds the document to the sessionSaveChangesAsync()commits to the database- ID is auto-generated if not provided
Reading Documents
Load by ID
Products/GetProductById/GetProductByIdHandler.cs
- Optimized for single document retrieval by ID
- Returns null if not found
- Uses PostgreSQL primary key index
Query with LINQ
Products/GetProducts/GetProductsHandler.cs
- Full LINQ support
- Translated to SQL queries
- Automatic JSONB field extraction
Filter by Property
Products/GetProductByCategory/GetProductByCategoryHandler.cs
Updating Documents
Products/UpdateProduct/UpdateProductHandler.cs
- Load existing document
- Modify properties in memory
- Call
Update()to mark as modified SaveChangesAsync()replaces the document
Deleting Documents
Products/DeleteProduct/DeleteProductHandler.cs
- Hard Delete: Removes document from database (default)
- Soft Delete: Marks as deleted but keeps in database (requires configuration)
Data Seeding
Initial Data Configuration
The service seeds initial data in development mode:Data/CatalogInitialData.cs
Seed Data Products
The initial dataset includes 7 products:| Product | Category | Price |
|---|---|---|
| IPhone X | Smart Phone | $950.00 |
| Samsung 10 | Smart Phone | $840.00 |
| Huawei Plus | White Appliances | $650.00 |
| Xiaomi Mi 9 | White Appliances | $470.00 |
| HTC U11+ Plus | Smart Phone | $380.00 |
| LG G7 ThinQ | Home Kitchen | $240.00 |
| Panasonic Lumix | Camera | $240.00 |
Advanced Features
Pagination
Marten provides built-in pagination:OFFSET and LIMIT:
Indexing
Marten automatically creates indexes, but you can configure custom ones:Transactions
Marten operations are transactional:Concurrency Control
Marten tracks document versions:Performance Considerations
Connection Pooling
PostgreSQL connection pooling is enabled by default:Query Optimization
Do:- Use
LoadAsync()for single document retrieval by ID - Add indexes on frequently queried properties
- Use pagination for large result sets
- Leverage JSONB GIN indexes for complex queries
- Load all documents without pagination
- Perform complex calculations in LINQ queries
- Use
Include()excessively (not relevant for documents)
Batch Operations
For bulk inserts, use batch operations:Monitoring
Database Health Check
The service includes PostgreSQL health monitoring:GET /health
Query Logging
Enable query logging in development:Backup and Migration
Database Backup
Use standard PostgreSQL backup tools:Schema Migration
Marten auto-creates and updates schema on startup. For production:Troubleshooting
Common Issues
Connection Errors:AutoCreateSchemaObjects is enabled for initial setup.
Serialization Errors:
References
Marten Documentation
Official Marten documentation
PostgreSQL JSONB
PostgreSQL JSON functions
