Monolith vs Service Overview
Monolithic Architecture
Magento 2 Monolith:
├── Catalog Module
├── Checkout Module
├── Order Module
├── Customer Module
├── Admin Module
└── All deployed as single unit
Pros:
├── Simple deployment
├── Easy debugging
├── No network overhead
├── ACID transactions
└── Simple testing
Cons:
├── Scaling entire application
├── Tight coupling
├── Large codebase
├── Long build times
└── Single point of failure
Microservices Architecture
Extracted Services:
├── Catalog Service (Products, Categories)
├── Inventory Service (Stock, Reservations)
├── Order Service (Orders, Fulfillment)
├── Payment Service (Payments, Refunds)
├── Customer Service (Accounts, Addresses)
└── Notification Service (Email, SMS)
Pros:
├── Independent scaling
├── Technology flexibility
├── Fault isolation
├── Team autonomy
└── Smaller deployments
Cons:
├── Network complexity
├── Distributed transactions
├── Service discovery
├── Data consistency
└── Operational overhead
When to Extract Services
Keep Monolith When:
1. Early stage startup
├── Small team (< 10 developers)
├── Simple domain
└── Limited traffic
2. Performance critical paths
├── Checkout flow
├── Payment processing
└── Real-time inventory
3. Strong consistency needed
├── Order processing
├── Inventory updates
└── Payment transactions
4. Simple deployment
├── Single server
├── Limited DevOps
└── Fast iteration needed
Extract Services When:
1. Scaling independently
├── Search: High read, low write
├── Catalog: High read, medium write
├── Orders: Medium read, medium write
└── Inventory: Low read, high write
2. Technology requirements
├── Search: Elasticsearch
├── Recommendations: ML/Python
├── Real-time: WebSockets
└── Analytics: Big data
3. Team boundaries
├── Catalog team
├── Checkout team
├── Fulfillment team
└── Each owns their service
4. Failure isolation
├── If search fails, checkout works
├── If notifications fail, orders work
└── If analytics fails, core works
Decomposition Strategies
Strangler Fig Pattern
// Gradually replace monolith with services
public function getOrder($id)
{
// Check if order should come from service
if ($this->featureFlag->isEnabled('order_service')) {
try {
return $this->orderServiceClient->get($id);
} catch (\Exception $e) {
// Fallback to monolith
$this->logger->warning('Order service failed, using monolith');
}
}
// Monolith implementation
return $this->orderRepository->getById($id);
}
Domain-Driven Design
Identify bounded contexts:
1. Catalog Context
├── Products
├── Categories
├── Attributes
└── Search
2. Inventory Context
├── Stock levels
├── Reservations
└── Sources
3. Order Context
├── Orders
├── Line items
└── Status
4. Payment Context
├── Payments
├── Refunds
└── Gateway
Each context → potential service boundary
API Gateway
Client Request Flow:
Client → API Gateway → Catalog Service
→ Inventory Service
→ Order Service
→ Payment Service
API Gateway responsibilities:
├── Request routing
├── Authentication
├── Rate limiting
├── Load balancing
└── Response aggregation
``
Data Management
Database per Service
Catalog Service:
├── catalog_product
├── catalog_category
└── catalog_product_index
Inventory Service:
├── inventory_stock
├── inventory_reservation
└── inventory_source
Order Service:
├── sales_order
├── sales_order_item
└── sales_order_status
Problem: Cross-service queries
Solution: API composition, event sourcing
Data Consistency
// Saga pattern for distributed transactions
class OrderSaga
{
public function createOrder($orderData)
{
try {
// 1. Reserve inventory
$this->inventoryService->reserve($orderData);
// 2. Process payment
$this->paymentService->charge($orderData);
// 3. Create order
$this->orderService->create($orderData);
// 4. Send confirmation
$this->notificationService->send($orderData);
} catch (\Exception $e) {
// Compensating transactions
$this->compensate($orderData, $e);
}
}
private function compensate($orderData, $error)
{
// Reverse operations in reverse order
$this->orderService->cancel($orderData);
$this->paymentService->refund($orderData);
$this->inventoryService->release($orderData);
}
}
Event-Driven Communication
// Publish events for cross-service communication
class OrderService
{
public function createOrder($orderData)
{
$order = $this->orderRepository->create($orderData);
// Publish event
$this->eventBus->publish('order.created', [
'order_id' => $order->getId(),
'items' => $order->getItems(),
'total' => $order->getTotal()
]);
}
}
// Subscribe to events
class InventorySubscriber
{
public function onOrderCreated($event)
{
$this->inventoryService->reserve($event->getItems());
}
}
// Notification subscriber
class NotificationSubscriber
{
public function onOrderCreated($event)
{
$this->emailService->sendConfirmation($event->getOrderId());
}
}
Practice Problems
Plan extraction of search and inventory from Magento monolith.
Solution
// Plan:
// 1. Search Service: Owns search index, Elasticsearch
// - Extract search logic
// - API: search, autocomplete, facets
// - Data: Search index (read from catalog)
// 2. Inventory Service: Owns stock, reservations
// - Extract inventory logic
// - API: check, reserve, release
// - Data: inventory_stock, inventory_reservation
// 3. Migration: Strangler Fig with feature flags
// 4. Fallback: Monolith implementation as backup Quiz
1. When should you keep the monolith?
2. What is the Strangler Fig pattern?
3. How to handle cross-service data consistency?
4. What is the main challenge of microservices?
Flashcards
Question
Keep monolith when?
Click to reveal answer
Answer
Small team, simple domain, limited traffic, fast iteration
Question
Extract services when?
Click to reveal answer
Answer
Need independent scaling, technology flexibility, fault isolation
Question
Strangler Fig pattern?
Click to reveal answer
Answer
Gradually replace monolith with services using feature flags
Question
Distributed transaction solution?
Click to reveal answer
Answer
Saga pattern with compensating transactions
Question
Cross-service communication?
Click to reveal answer
Answer
Event-driven with publish/subscribe pattern
Revision Notes
Key Takeaways
- 1. Monolith: Simple, good for small teams, fast iteration
- 2. Microservices: Scalable, fault-isolated, technology flexible
- 3. Strangler Fig: Gradually replace monolith with services
- 4. Saga pattern: Handle distributed transactions
- 5. Event-driven: Loose coupling between services
Interview Tips
- • Compare monolith vs microservices trade-offs
- • Explain decomposition strategies
- • Discuss data consistency challenges
- • Know when to keep monolith vs extract
Cheat Sheet
Monolith vs Services
- Monolith: Simple, small team, fast iteration
- Services: Scalable, flexible, fault-isolated
- Strangler Fig: Gradual replacement
- Saga: Distributed transactions
- Event-driven: Loose coupling
- Extract when: Scaling, tech needs, team boundaries