Files
Alexander Abakumov 15e744da49 Initial commit: Complete Software Architecture course with 11 modules
- Added comprehensive course structure with 11 modules
- Included theoretical content, practical examples, and tasks
- Multi-language code examples (Java, Rust, Node.js, Python)
- Detailed analysis of architectural approaches and trade-offs
- Complete caching strategies documentation
- Architecture examples from real-world systems (Twitter, Netflix, Uber)
- Structured navigation and learning path
- Ready for educational use
2025-09-09 22:08:07 +03:00

9.4 KiB

Реализация архитектуры

Навигация


Структура проекта

1. Monorepo Structure

ecommerce-platform/
├── services/
│   ├── user-service/
│   │   ├── src/
│   │   ├── Dockerfile
│   │   ├── pom.xml
│   │   └── README.md
│   ├── product-service/
│   ├── order-service/
│   ├── payment-service/
│   └── inventory-service/
├── frontend/
│   ├── customer-app/
│   ├── admin-app/
│   └── shared/
├── infrastructure/
│   ├── kubernetes/
│   ├── terraform/
│   └── docker-compose/
├── docs/
│   ├── architecture/
│   ├── api/
│   └── deployment/
└── scripts/
    ├── build.sh
    ├── deploy.sh
    └── test.sh

2. Service Implementation

// Order Service Implementation
@RestController
@RequestMapping("/api/orders")
@Validated
public class OrderController {
    
    @Autowired
    private OrderService orderService;
    
    @PostMapping
    public ResponseEntity<OrderResponse> createOrder(
            @Valid @RequestBody CreateOrderRequest request) {
        
        Order order = orderService.createOrder(request);
        OrderResponse response = OrderMapper.toResponse(order);
        
        return ResponseEntity.status(HttpStatus.CREATED).body(response);
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<OrderResponse> getOrder(@PathVariable Long id) {
        Order order = orderService.getOrder(id);
        OrderResponse response = OrderMapper.toResponse(order);
        
        return ResponseEntity.ok(response);
    }
    
    @PutMapping("/{id}/status")
    public ResponseEntity<OrderResponse> updateOrderStatus(
            @PathVariable Long id,
            @Valid @RequestBody UpdateOrderStatusRequest request) {
        
        Order order = orderService.updateOrderStatus(id, request.getStatus());
        OrderResponse response = OrderMapper.toResponse(order);
        
        return ResponseEntity.ok(response);
    }
}

@Service
@Transactional
public class OrderService {
    
    @Autowired
    private OrderRepository orderRepository;
    
    @Autowired
    private OrderEventPublisher eventPublisher;
    
    @Autowired
    private InventoryServiceClient inventoryClient;
    
    @Autowired
    private PaymentServiceClient paymentClient;
    
    public Order createOrder(CreateOrderRequest request) {
        // Валидация заказа
        validateOrderRequest(request);
        
        // Создание заказа
        Order order = new Order(request);
        order = orderRepository.save(order);
        
        // Резервирование товаров
        inventoryClient.reserveItems(order.getId(), request.getItems());
        
        // Публикация события
        eventPublisher.publishOrderCreated(order);
        
        return order;
    }
    
    public Order updateOrderStatus(Long orderId, OrderStatus status) {
        Order order = orderRepository.findById(orderId)
            .orElseThrow(() -> new OrderNotFoundException("Order not found: " + orderId));
        
        order.updateStatus(status);
        order = orderRepository.save(order);
        
        // Публикация события
        eventPublisher.publishOrderStatusUpdated(order);
        
        return order;
    }
    
    private void validateOrderRequest(CreateOrderRequest request) {
        if (request.getItems().isEmpty()) {
            throw new ValidationException("Order must contain at least one item");
        }
        
        // Дополнительные проверки...
    }
}

Проектирование API

1. REST API Specification

# OpenAPI Specification
openapi: 3.0.0
info:
  title: E-commerce Platform API
  version: 1.0.0
  description: API for e-commerce platform

servers:
  - url: https://api.ecommerce.com/v1
    description: Production server

paths:
  /orders:
    post:
      summary: Create a new order
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateOrderRequest'
      responses:
        '201':
          description: Order created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrderResponse'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /orders/{id}:
    get:
      summary: Get order by ID
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Order retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrderResponse'
        '404':
          description: Order not found

components:
  schemas:
    CreateOrderRequest:
      type: object
      required:
        - customerId
        - items
      properties:
        customerId:
          type: integer
          format: int64
        items:
          type: array
          items:
            $ref: '#/components/schemas/OrderItem'
        shippingAddress:
          $ref: '#/components/schemas/Address'
        paymentMethod:
          $ref: '#/components/schemas/PaymentMethod'
    
    OrderResponse:
      type: object
      properties:
        id:
          type: integer
          format: int64
        customerId:
          type: integer
          format: int64
        status:
          type: string
          enum: [PENDING, CONFIRMED, SHIPPED, DELIVERED, CANCELLED]
        totalAmount:
          type: number
          format: decimal
        items:
          type: array
          items:
            $ref: '#/components/schemas/OrderItem'
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

2. Event Schema

{
  "orderCreated": {
    "eventType": "OrderCreated",
    "version": "1.0",
    "timestamp": "2023-12-01T10:00:00Z",
    "data": {
      "orderId": "12345",
      "customerId": "67890",
      "items": [
        {
          "productId": "prod-001",
          "quantity": 2,
          "price": 29.99
        }
      ],
      "totalAmount": 59.98,
      "status": "PENDING"
    }
  },
  "orderStatusUpdated": {
    "eventType": "OrderStatusUpdated",
    "version": "1.0",
    "timestamp": "2023-12-01T10:05:00Z",
    "data": {
      "orderId": "12345",
      "oldStatus": "PENDING",
      "newStatus": "CONFIRMED",
      "updatedBy": "system"
    }
  }
}

Проектирование базы данных

1. Database Schema

-- Order Service Database Schema
CREATE TABLE orders (
    id BIGSERIAL PRIMARY KEY,
    customer_id BIGINT NOT NULL,
    status VARCHAR(20) NOT NULL DEFAULT 'PENDING',
    total_amount DECIMAL(10,2) NOT NULL,
    shipping_address JSONB,
    payment_method JSONB,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE order_items (
    id BIGSERIAL PRIMARY KEY,
    order_id BIGINT NOT NULL REFERENCES orders(id),
    product_id VARCHAR(50) NOT NULL,
    quantity INTEGER NOT NULL,
    unit_price DECIMAL(10,2) NOT NULL,
    total_price DECIMAL(10,2) NOT NULL
);

CREATE TABLE order_events (
    id BIGSERIAL PRIMARY KEY,
    order_id BIGINT NOT NULL,
    event_type VARCHAR(50) NOT NULL,
    event_data JSONB NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Индексы для оптимизации
CREATE INDEX idx_orders_customer_id ON orders(customer_id);
CREATE INDEX idx_orders_status ON orders(status);
CREATE INDEX idx_orders_created_at ON orders(created_at);
CREATE INDEX idx_order_items_order_id ON order_items(order_id);
CREATE INDEX idx_order_events_order_id ON order_events(order_id);

2. Data Access Layer

@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
    
    List<Order> findByCustomerId(Long customerId);
    
    List<Order> findByStatus(OrderStatus status);
    
    @Query("SELECT o FROM Order o WHERE o.createdAt BETWEEN :startDate AND :endDate")
    List<Order> findOrdersByDateRange(
        @Param("startDate") LocalDateTime startDate,
        @Param("endDate") LocalDateTime endDate
    );
    
    @Query("SELECT o FROM Order o WHERE o.customerId = :customerId AND o.status = :status")
    List<Order> findByCustomerIdAndStatus(
        @Param("customerId") Long customerId,
        @Param("status") OrderStatus status
    );
}

@Repository
public class OrderEventRepository {
    
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    public void saveEvent(OrderEvent event) {
        String sql = "INSERT INTO order_events (order_id, event_type, event_data) VALUES (?, ?, ?)";
        
        jdbcTemplate.update(sql, 
            event.getOrderId(),
            event.getEventType(),
            event.getEventData()
        );
    }
    
    public List<OrderEvent> findEventsByOrderId(Long orderId) {
        String sql = "SELECT * FROM order_events WHERE order_id = ? ORDER BY created_at";
        
        return jdbcTemplate.query(sql, new OrderEventRowMapper(), orderId);
    }
}