Refactoring & Code Quality with AI
Code refactoring is the art of improving code structure without changing its functionality. With AI assistance, refactoring becomes more systematic, comprehensive, and guided by best practices. AI can identify code smells, suggest architectural improvements, and help transform legacy code into modern, maintainable solutions.
IDE's Automated Refactoring Tools
Before leveraging AI, master your IDE's built-in refactoring capabilities. These tools provide safe, automated transformations that preserve functionality while improving code structure.
Essential IDE Refactoring Commands
Universal Refactoring Shortcuts:
F2 - Rename Symbol (works across all files)
Ctrl+R, Ctrl+M - Extract Method
Ctrl+R, Ctrl+V - Extract Variable
Ctrl+R, Ctrl+F - Extract Field
Ctrl+R, Ctrl+I - Extract Interface
VS Code Refactoring Examples:
Extract Method:
// Before: Complex function doing too much
function processUserOrder(user: User, items: CartItem[], paymentInfo: PaymentInfo) {
// Validation logic (select this block)
if (!user || !user.email) {
throw new Error('Invalid user');
}
if (!items || items.length === 0) {
throw new Error('Cart is empty');
}
for (const item of items) {
if (item.quantity <= 0 || item.price < 0) {
throw new Error('Invalid item data');
}
}
// Select validation block and press Ctrl+Shift+R
// VS Code will suggest extracting to a new method
// Calculate total
const total = items.reduce((sum, item) => sum + (item.price * item.quantity), 0);
// Process payment
const payment = processPayment(paymentInfo, total);
return { orderId: generateOrderId(), payment, total };
}
// After extraction:
function validateOrderData(user: User, items: CartItem[]) {
if (!user || !user.email) {
throw new Error('Invalid user');
}
if (!items || items.length === 0) {
throw new Error('Cart is empty');
}
for (const item of items) {
if (item.quantity <= 0 || item.price < 0) {
throw new Error('Invalid item data');
}
}
}
function processUserOrder(user: User, items: CartItem[], paymentInfo: PaymentInfo) {
validateOrderData(user, items);
const total = items.reduce((sum, item) => sum + (item.price * item.quantity), 0);
const payment = processPayment(paymentInfo, total);
return { orderId: generateOrderId(), payment, total };
}
IntelliJ IDEA Advanced Refactoring:
Safe Delete with Dependency Analysis:
// IntelliJ can safely delete methods/classes and show what depends on them
public class UserService {
@Deprecated
public void oldMethod() {
// This method is deprecated but might still be used
}
// Alt+Delete on oldMethod shows all usages before deletion
// IntelliJ prevents deletion if it would break code
}
Change Signature:
// Before
public User createUser(String name, String email) {
return new User(name, email);
}
// After using "Change Signature" refactoring (Ctrl+F6)
public User createUser(String name, String email, UserRole role, boolean isActive) {
return new User(name, email, role, isActive);
}
// IntelliJ automatically updates all callers with default values
AI as Your Code Review Partner
AI excels at identifying patterns, suggesting improvements, and catching issues that might be missed in manual code reviews.
Comprehensive Code Analysis
AI-Powered Code Review Prompt:
Review this Python function for:
- Code smells and design issues
- Performance problems
- Security vulnerabilities
- Pythonic improvements
- Error handling
- Type safety
```python
def process_user_data(data):
results = []
for item in data:
if item['type'] == 'user':
user_info = {}
user_info['id'] = item['id']
user_info['name'] = item['name'].strip().title()
user_info['email'] = item['email'].lower()
# Validate email
if '@' in user_info['email'] and '.' in user_info['email']:
user_info['email_valid'] = True
else:
user_info['email_valid'] = False
# Calculate age
if 'birth_date' in item:
try:
birth_year = int(item['birth_date'].split('-')[0])
current_year = 2025
user_info['age'] = current_year - birth_year
except:
user_info['age'] = None
# Get user permissions
permissions = []
if item.get('is_admin'):
permissions.append('admin')
if item.get('is_editor'):
permissions.append('editor')
if item.get('can_view'):
permissions.append('viewer')
user_info['permissions'] = permissions
results.append(user_info)
return results
**AI Analysis & Improvements:**
```python
from dataclasses import dataclass
from datetime import datetime
from email_validator import validate_email, EmailNotValidError
from typing import List, Optional, Dict, Any
import logging
logger = logging.getLogger(__name__)
@dataclass
class UserPermissions:
is_admin: bool = False
is_editor: bool = False
can_view: bool = False
def to_list(self) -> List[str]:
"""Convert permissions to list of strings."""
permissions = []
if self.is_admin:
permissions.append('admin')
if self.is_editor:
permissions.append('editor')
if self.can_view:
permissions.append('viewer')
return permissions
@dataclass
class ProcessedUser:
id: str
name: str
email: str
email_valid: bool
age: Optional[int]
permissions: List[str]
class UserDataProcessor:
"""Processes raw user data into structured format."""
def __init__(self, current_year: int = None):
self.current_year = current_year or datetime.now().year
def process_user_data(self, data: List[Dict[str, Any]]) -> List[ProcessedUser]:
"""
Process list of user data dictionaries into ProcessedUser objects.
Args:
data: List of dictionaries containing user information
Returns:
List of ProcessedUser objects
Raises:
ValueError: If data is invalid or empty
"""
if not data:
raise ValueError("Data cannot be empty")
if not isinstance(data, list):
raise ValueError("Data must be a list")
results = []
for index, item in enumerate(data):
try:
if not isinstance(item, dict):
logger.warning(f"Skipping non-dict item at index {index}")
continue
if item.get('type') != 'user':
continue
processed_user = self._process_single_user(item)
if processed_user:
results.append(processed_user)
except Exception as e:
logger.error(f"Error processing item at index {index}: {e}")
continue
return results
def _process_single_user(self, item: Dict[str, Any]) -> Optional[ProcessedUser]:
"""Process a single user dictionary."""
# Validate required fields
required_fields = ['id', 'name', 'email']
for field in required_fields:
if field not in item or not item[field]:
logger.warning(f"Missing required field '{field}', skipping user")
return None
try:
return ProcessedUser(
id=str(item['id']),
name=self._clean_name(item['name']),
email=self._clean_email(item['email']),
email_valid=self._validate_email(item['email']),
age=self._calculate_age(item.get('birth_date')),
permissions=self._extract_permissions(item).to_list()
)
except Exception as e:
logger.error(f"Error creating ProcessedUser: {e}")
return None
def _clean_name(self, name: str) -> str:
"""Clean and format user name."""
if not isinstance(name, str):
raise ValueError("Name must be a string")
return name.strip().title()
def _clean_email(self, email: str) -> str:
"""Clean and format email address."""
if not isinstance(email, str):
raise ValueError("Email must be a string")
return email.strip().lower()
def _validate_email(self, email: str) -> bool:
"""Validate email address using proper email validation."""
try:
validate_email(email)
return True
except EmailNotValidError:
return False
def _calculate_age(self, birth_date: Optional[str]) -> Optional[int]:
"""Calculate age from birth date string."""
if not birth_date:
return None
try:
# Handle different date formats
if '-' in birth_date:
birth_year = int(birth_date.split('-')[0])
elif '/' in birth_date:
parts = birth_date.split('/')
# Assume MM/DD/YYYY or DD/MM/YYYY format
birth_year = int(parts[-1])
else:
# Try to parse as year only
birth_year = int(birth_date)
if birth_year < 1900 or birth_year > self.current_year:
logger.warning(f"Invalid birth year: {birth_year}")
return None
age = self.current_year - birth_year
return age if 0 <= age <= 150 else None
except (ValueError, IndexError) as e:
logger.warning(f"Could not parse birth date '{birth_date}': {e}")
return None
def _extract_permissions(self, item: Dict[str, Any]) -> UserPermissions:
"""Extract user permissions from item dictionary."""
return UserPermissions(
is_admin=bool(item.get('is_admin', False)),
is_editor=bool(item.get('is_editor', False)),
can_view=bool(item.get('can_view', False))
)
# Usage example
def process_users_from_api(raw_data: List[Dict[str, Any]]) -> List[ProcessedUser]:
"""High-level function to process user data from API."""
processor = UserDataProcessor()
return processor.process_user_data(raw_data)
# Example with error handling
if __name__ == "__main__":
sample_data = [
{
'type': 'user',
'id': '123',
'name': ' john doe ',
'email': 'JOHN@EXAMPLE.COM',
'birth_date': '1990-05-15',
'is_admin': True,
'can_view': True
}
]
try:
users = process_users_from_api(sample_data)
for user in users:
print(f"Processed user: {user}")
except Exception as e:
logger.error(f"Failed to process users: {e}")
Advanced Refactoring with AI
Legacy Code Modernization
AI Prompt for Legacy Java to Modern Java:
Modernize this legacy Java code to use:
- Modern Java features (records, sealed classes, pattern matching)
- Proper exception handling
- Stream API where appropriate
- Optional for null handling
- Immutable design patterns
```java
public class LegacyOrderProcessor {
private List orders;
private Map customerCache;
public LegacyOrderProcessor() {
this.orders = new ArrayList();
this.customerCache = new HashMap();
}
public String processOrder(Object orderData) {
if (orderData == null) {
return "ERROR: No order data";
}
Map order = (Map) orderData;
String customerId = (String) order.get("customerId");
List items = (List) order.get("items");
if (customerId == null || items == null) {
return "ERROR: Missing required fields";
}
Object customer = customerCache.get(customerId);
if (customer == null) {
customer = loadCustomer(customerId);
if (customer == null) {
return "ERROR: Customer not found";
}
customerCache.put(customerId, customer);
}
double total = 0;
for (Object item : items) {
Map itemMap = (Map) item;
Double price = (Double) itemMap.get("price");
Integer quantity = (Integer) itemMap.get("quantity");
if (price != null && quantity != null) {
total += price * quantity;
}
}
String orderId = generateOrderId();
orders.add(order);
return "SUCCESS: Order " + orderId + " processed for total: $" + total;
}
private Object loadCustomer(String customerId) {
// Simulate database call
if ("123".equals(customerId)) {
Map customer = new HashMap();
customer.put("id", customerId);
customer.put("name", "John Doe");
return customer;
}
return null;
}
private String generateOrderId() {
return "ORD-" + System.currentTimeMillis();
}
}
**AI Modernized Version:**
```java
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
// Modern records for data transfer
public record OrderItem(
String id,
BigDecimal price,
int quantity
) {
public OrderItem {
if (price == null || price.compareTo(BigDecimal.ZERO) < 0) {
throw new IllegalArgumentException("Price must be non-negative");
}
if (quantity <= 0) {
throw new IllegalArgumentException("Quantity must be positive");
}
}
public BigDecimal getTotal() {
return price.multiply(BigDecimal.valueOf(quantity));
}
}
public record Customer(
String id,
String name,
String email
) {
public Customer {
Objects.requireNonNull(id, "Customer ID cannot be null");
Objects.requireNonNull(name, "Customer name cannot be null");
}
}
public record OrderRequest(
String customerId,
List<OrderItem> items
) {
public OrderRequest {
Objects.requireNonNull(customerId, "Customer ID cannot be null");
Objects.requireNonNull(items, "Items list cannot be null");
if (items.isEmpty()) {
throw new IllegalArgumentException("Order must contain at least one item");
}
}
}
// Sealed class for result types
public sealed interface OrderResult
permits OrderResult.Success, OrderResult.Failure {
record Success(
String orderId,
BigDecimal total,
LocalDateTime processedAt
) implements OrderResult {}
record Failure(
String errorCode,
String message,
Exception cause
) implements OrderResult {}
}
// Modern exception hierarchy
public class OrderProcessingException extends Exception {
public OrderProcessingException(String message) {
super(message);
}
public OrderProcessingException(String message, Throwable cause) {
super(message, cause);
}
}
public class CustomerNotFoundException extends OrderProcessingException {
public CustomerNotFoundException(String customerId) {
super("Customer not found: " + customerId);
}
}
// Main processor class
public class ModernOrderProcessor {
private final Map<String, Customer> customerCache = new ConcurrentHashMap<>();
private final List<OrderRequest> processedOrders = new ArrayList<>();
private final CustomerRepository customerRepository;
public ModernOrderProcessor(CustomerRepository customerRepository) {
this.customerRepository = Objects.requireNonNull(customerRepository);
}
public OrderResult processOrder(OrderRequest orderRequest) {
try {
// Validate input
Objects.requireNonNull(orderRequest, "Order request cannot be null");
// Load customer with caching
Customer customer = loadCustomerWithCaching(orderRequest.customerId())
.orElseThrow(() -> new CustomerNotFoundException(orderRequest.customerId()));
// Calculate total using streams
BigDecimal total = calculateTotal(orderRequest.items());
// Generate order ID
String orderId = generateOrderId();
// Store processed order
processedOrders.add(orderRequest);
return new OrderResult.Success(
orderId,
total,
LocalDateTime.now()
);
} catch (OrderProcessingException e) {
return new OrderResult.Failure(
"PROCESSING_ERROR",
e.getMessage(),
e
);
} catch (Exception e) {
return new OrderResult.Failure(
"UNEXPECTED_ERROR",
"An unexpected error occurred while processing the order",
e
);
}
}
private Optional<Customer> loadCustomerWithCaching(String customerId)
throws OrderProcessingException {
return Optional.ofNullable(
customerCache.computeIfAbsent(customerId, id -> {
try {
return customerRepository.findById(id).orElse(null);
} catch (Exception e) {
throw new RuntimeException("Failed to load customer: " + id, e);
}
})
);
}
private BigDecimal calculateTotal(List<OrderItem> items) {
return items.stream()
.map(OrderItem::getTotal)
.reduce(BigDecimal.ZERO, BigDecimal::add)
.setScale(2, RoundingMode.HALF_UP);
}
private String generateOrderId() {
return "ORD-" + System.currentTimeMillis() + "-" +
UUID.randomUUID().toString().substring(0, 8).toUpperCase();
}
// Pattern matching for result handling (Java 17+)
public String formatResult(OrderResult result) {
return switch (result) {
case OrderResult.Success(var orderId, var total, var processedAt) ->
String.format("SUCCESS: Order %s processed for total: $%.2f at %s",
orderId, total, processedAt);
case OrderResult.Failure(var errorCode, var message, var cause) ->
String.format("FAILED [%s]: %s", errorCode, message);
};
}
// Get statistics using streams
public OrderStatistics getStatistics() {
var totalOrders = processedOrders.size();
var totalValue = processedOrders.stream()
.flatMap(order -> order.items().stream())
.map(OrderItem::getTotal)
.reduce(BigDecimal.ZERO, BigDecimal::add);
var averageOrderValue = totalOrders > 0
? totalValue.divide(BigDecimal.valueOf(totalOrders), 2, RoundingMode.HALF_UP)
: BigDecimal.ZERO;
return new OrderStatistics(totalOrders, totalValue, averageOrderValue);
}
}
public record OrderStatistics(
int totalOrders,
BigDecimal totalValue,
BigDecimal averageOrderValue
) {}
// Repository interface for dependency injection
public interface CustomerRepository {
Optional<Customer> findById(String id);
}
// Usage example with proper error handling
public class OrderProcessorExample {
public static void main(String[] args) {
CustomerRepository repository = customerId -> {
if ("123".equals(customerId)) {
return Optional.of(new Customer("123", "John Doe", "john@example.com"));
}
return Optional.empty();
};
ModernOrderProcessor processor = new ModernOrderProcessor(repository);
OrderRequest request = new OrderRequest(
"123",
List.of(
new OrderItem("item1", new BigDecimal("29.99"), 2),
new OrderItem("item2", new BigDecimal("15.50"), 1)
)
);
OrderResult result = processor.processOrder(request);
System.out.println(processor.formatResult(result));
// Pattern matching for different result types
switch (result) {
case OrderResult.Success success -> {
System.out.println("Order processed successfully!");
System.out.println("Order ID: " + success.orderId());
System.out.println("Total: $" + success.total());
}
case OrderResult.Failure failure -> {
System.err.println("Order processing failed: " + failure.message());
if (failure.cause() != null) {
failure.cause().printStackTrace();
}
}
}
}
}
Architectural Refactoring with AI
Microservices Decomposition
AI Prompt for Monolith to Microservices:
Help me decompose this monolithic service into microservices. Identify:
- Service boundaries based on domain concepts
- Data ownership and database splitting
- Communication patterns between services
- Shared concerns (authentication, logging, etc.)
- Migration strategy
```typescript
// Current monolithic e-commerce service
class ECommerceService {
// User management
async createUser(userData: any) { /* ... */ }
async authenticateUser(credentials: any) { /* ... */ }
async updateUserProfile(userId: string, data: any) { /* ... */ }
// Product catalog
async addProduct(productData: any) { /* ... */ }
async updateProduct(productId: string, data: any) { /* ... */ }
async searchProducts(criteria: any) { /* ... */ }
async getProductRecommendations(userId: string) { /* ... */ }
// Inventory management
async updateInventory(productId: string, quantity: number) { /* ... */ }
async checkAvailability(productId: string) { /* ... */ }
async reserveItems(items: any[]) { /* ... */ }
// Order processing
async createOrder(orderData: any) { /* ... */ }
async processPayment(paymentData: any) { /* ... */ }
async updateOrderStatus(orderId: string, status: string) { /* ... */ }
async calculateShipping(orderData: any) { /* ... */ }
// Notifications
async sendOrderConfirmation(orderId: string) { /* ... */ }
async sendShippingNotification(orderId: string) { /* ... */ }
async sendMarketingEmail(userId: string, campaign: any) { /* ... */ }
}
**AI Microservices Decomposition:**
```typescript
// 1. User Service - Handles authentication and user management
interface UserService {
createUser(userData: CreateUserRequest): Promise<User>;
authenticateUser(credentials: AuthCredentials): Promise<AuthToken>;
updateUserProfile(userId: string, data: UpdateUserRequest): Promise<User>;
getUserById(userId: string): Promise<User>;
validateToken(token: string): Promise<TokenValidation>;
}
// 2. Product Catalog Service - Manages product information
interface ProductCatalogService {
addProduct(productData: CreateProductRequest): Promise<Product>;
updateProduct(productId: string, data: UpdateProductRequest): Promise<Product>;
getProduct(productId: string): Promise<Product>;
searchProducts(criteria: SearchCriteria): Promise<SearchResult>;
getProductsByCategory(categoryId: string): Promise<Product[]>;
}
// 3. Recommendation Service - Handles product recommendations
interface RecommendationService {
getProductRecommendations(userId: string): Promise<Recommendation[]>;
updateUserPreferences(userId: string, preferences: UserPreferences): Promise<void>;
trackUserInteraction(userId: string, interaction: UserInteraction): Promise<void>;
}
// 4. Inventory Service - Manages stock and availability
interface InventoryService {
updateInventory(productId: string, quantity: number): Promise<InventoryUpdate>;
checkAvailability(productId: string): Promise<AvailabilityStatus>;
reserveItems(items: ReservationRequest[]): Promise<ReservationResult>;
releaseReservation(reservationId: string): Promise<void>;
getInventoryStatus(productIds: string[]): Promise<InventoryStatus[]>;
}
// 5. Order Service - Handles order lifecycle
interface OrderService {
createOrder(orderData: CreateOrderRequest): Promise<Order>;
updateOrderStatus(orderId: string, status: OrderStatus): Promise<Order>;
getOrder(orderId: string): Promise<Order>;
getUserOrders(userId: string): Promise<Order[]>;
cancelOrder(orderId: string): Promise<CancelationResult>;
}
// 6. Payment Service - Handles all payment processing
interface PaymentService {
processPayment(paymentData: PaymentRequest): Promise<PaymentResult>;
refundPayment(paymentId: string, amount: number): Promise<RefundResult>;
getPaymentStatus(paymentId: string): Promise<PaymentStatus>;
updatePaymentMethod(userId: string, paymentMethod: PaymentMethod): Promise<void>;
}
// 7. Shipping Service - Calculates shipping and handles logistics
interface ShippingService {
calculateShipping(orderData: ShippingCalculationRequest): Promise<ShippingOptions>;
createShipment(shipmentData: CreateShipmentRequest): Promise<Shipment>;
trackShipment(trackingNumber: string): Promise<TrackingInfo>;
updateShipmentStatus(shipmentId: string, status: ShipmentStatus): Promise<void>;
}
// 8. Notification Service - Handles all communications
interface NotificationService {
sendOrderConfirmation(orderId: string): Promise<NotificationResult>;
sendShippingNotification(orderId: string): Promise<NotificationResult>;
sendMarketingEmail(userId: string, campaign: MarketingCampaign): Promise<NotificationResult>;
sendSMS(userId: string, message: string): Promise<NotificationResult>;
createNotificationTemplate(template: NotificationTemplate): Promise<void>;
}
// Service Communication Patterns
// 1. Synchronous communication for immediate consistency
class OrderOrchestrator {
constructor(
private userService: UserService,
private productService: ProductCatalogService,
private inventoryService: InventoryService,
private paymentService: PaymentService,
private eventBus: EventBus
) {}
async createOrder(orderRequest: CreateOrderRequest): Promise<OrderResult> {
try {
// 1. Validate user
const user = await this.userService.getUserById(orderRequest.userId);
// 2. Validate products and get pricing
const products = await Promise.all(
orderRequest.items.map(item =>
this.productService.getProduct(item.productId)
)
);
// 3. Reserve inventory
const reservation = await this.inventoryService.reserveItems(
orderRequest.items.map(item => ({
productId: item.productId,
quantity: item.quantity
}))
);
if (!reservation.success) {
throw new InsufficientInventoryError(reservation.unavailableItems);
}
// 4. Process payment
const payment = await this.paymentService.processPayment({
amount: orderRequest.total,
paymentMethod: orderRequest.paymentMethod,
userId: orderRequest.userId
});
if (!payment.success) {
// Rollback inventory reservation
await this.inventoryService.releaseReservation(reservation.reservationId);
throw new PaymentFailedError(payment.error);
}
// 5. Create order
const order = await this.orderService.createOrder({
...orderRequest,
paymentId: payment.paymentId,
reservationId: reservation.reservationId
});
// 6. Publish order created event
await this.eventBus.publish(new OrderCreatedEvent(order));
return { success: true, order };
} catch (error) {
// Handle rollbacks and error scenarios
await this.handleOrderCreationError(error, orderRequest);
throw error;
}
}
}
// 2. Event-driven communication for eventual consistency
interface EventBus {
publish(event: DomainEvent): Promise<void>;
subscribe<T extends DomainEvent>(
eventType: string,
handler: (event: T) => Promise<void>
): void;
}
// Domain Events
abstract class DomainEvent {
constructor(
public readonly eventId: string = uuid(),
public readonly timestamp: Date = new Date(),
public readonly version: number = 1
) {}
}
class OrderCreatedEvent extends DomainEvent {
constructor(public readonly order: Order) {
super();
}
}
class PaymentProcessedEvent extends DomainEvent {
constructor(
public readonly orderId: string,
public readonly paymentId: string,
public readonly amount: number
) {
super();
}
}
// Event Handlers
class NotificationEventHandler {
constructor(private notificationService: NotificationService) {}
@EventHandler(OrderCreatedEvent)
async handleOrderCreated(event: OrderCreatedEvent): Promise<void> {
await this.notificationService.sendOrderConfirmation(event.order.id);
}
@EventHandler(PaymentProcessedEvent)
async handlePaymentProcessed(event: PaymentProcessedEvent): Promise<void> {
await this.notificationService.sendPaymentConfirmation(
event.orderId,
event.paymentId
);
}
}
// Database Design per Service
interface ServiceDatabases {
// User Service - PostgreSQL for ACID compliance
userDatabase: {
users: UserTable;
user_profiles: UserProfileTable;
user_sessions: SessionTable;
};
// Product Catalog - PostgreSQL with search capabilities
productDatabase: {
products: ProductTable;
categories: CategoryTable;
product_attributes: AttributeTable;
};
// Inventory - PostgreSQL for consistency
inventoryDatabase: {
inventory: InventoryTable;
reservations: ReservationTable;
inventory_movements: MovementTable;
};
// Recommendations - MongoDB for flexible schema
recommendationDatabase: {
user_preferences: UserPreferenceDocument;
interaction_history: InteractionDocument;
recommendation_models: ModelDocument;
};
// Orders - PostgreSQL for transactional integrity
orderDatabase: {
orders: OrderTable;
order_items: OrderItemTable;
order_status_history: StatusHistoryTable;
};
}
// API Gateway Configuration
class APIGateway {
private routes = new Map<string, ServiceRoute>();
constructor() {
this.setupRoutes();
}
private setupRoutes(): void {
// User Service routes
this.routes.set('POST /api/users', {
service: 'user-service',
endpoint: '/users',
auth: false
});
this.routes.set('GET /api/users/:id', {
service: 'user-service',
endpoint: '/users/:id',
auth: true
});
// Product routes
this.routes.set('GET /api/products', {
service: 'product-catalog-service',
endpoint: '/products',
auth: false,
cache: { ttl: 300 } // 5 minutes
});
// Order routes
this.routes.set('POST /api/orders', {
service: 'order-orchestrator',
endpoint: '/orders',
auth: true,
rateLimit: { max: 10, window: 60000 } // 10 requests per minute
});
}
}
// Migration Strategy
class MigrationStrategy {
// Phase 1: Extract User Service
async phase1_ExtractUserService(): Promise<void> {
// 1. Create new user service
// 2. Implement database replication
// 3. Route authentication through new service
// 4. Migrate user management endpoints
// 5. Validate data consistency
}
// Phase 2: Extract Product Catalog
async phase2_ExtractProductCatalog(): Promise<void> {
// 1. Create product catalog service
// 2. Migrate product data
// 3. Update product management endpoints
// 4. Implement product search
}
// Continue for each service...
}
Your code is now maintainable, scalable, and follows modern architectural patterns.
Next: Learn how to integrate databases and data analysis tools in Data Integration.