<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: rezahazegh</title>
    <description>The latest articles on DEV Community by rezahazegh (@reza_sh).</description>
    <link>https://dev.to/reza_sh</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F912692%2Fa6d9cb7c-7fe3-4e38-9d5d-f62691c6e006.png</url>
      <title>DEV Community: rezahazegh</title>
      <link>https://dev.to/reza_sh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/reza_sh"/>
    <language>en</language>
    <item>
      <title>Hexagonal Architecture Demo - Task Management System</title>
      <dc:creator>rezahazegh</dc:creator>
      <pubDate>Sun, 28 Dec 2025 14:26:09 +0000</pubDate>
      <link>https://dev.to/reza_sh/hexagonal-architecture-demo-task-management-system-3g6f</link>
      <guid>https://dev.to/reza_sh/hexagonal-architecture-demo-task-management-system-3g6f</guid>
      <description>&lt;p&gt;A Spring Boot application demonstrating &lt;strong&gt;Hexagonal Architecture&lt;/strong&gt; (also known as &lt;strong&gt;Ports and Adapters&lt;/strong&gt;) with a Task Management system. This project showcases clean separation of concerns, dependency inversion, and testable code structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  📄 Repository
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/rezahazegh/demo-hexagonal-architecture" rel="noopener noreferrer"&gt;https://github.com/rezahazegh/demo-hexagonal-architecture&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  📋 Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Architecture Overview&lt;/li&gt;
&lt;li&gt;What is Hexagonal Architecture?&lt;/li&gt;
&lt;li&gt;Project Structure&lt;/li&gt;
&lt;li&gt;Key Design Principles&lt;/li&gt;
&lt;li&gt;Technologies Used&lt;/li&gt;
&lt;li&gt;Getting Started&lt;/li&gt;
&lt;li&gt;API Documentation&lt;/li&gt;
&lt;li&gt;Testing&lt;/li&gt;
&lt;li&gt;Benefits of This Architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🏗️ Architecture Overview
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────────┐
│                     Infrastructure Layer                      │
│  ┌──────────────────────────────────────────────────────┐   │
│  │              Inbound Adapters (Input)                │   │
│  │         REST API Controllers &amp;amp; DTOs                   │   │
│  └──────────────────┬───────────────────────────────────┘   │
│                     │                                         │
│  ┌─────────────────▼────────────────────────────────────┐   │
│  │              Application Layer                        │   │
│  │        Use Cases &amp;amp; Business Orchestration             │   │
│  └─────────────────┬────────────────────────────────────┘   │
│                     │                                         │
│  ┌─────────────────▼────────────────────────────────────┐   │
│  │                Domain Layer (Core)                    │   │
│  │        Business Logic &amp;amp; Domain Models                 │   │
│  │              No External Dependencies                 │   │
│  └─────────────────┬────────────────────────────────────┘   │
│                     │                                         │
│  ┌─────────────────▼────────────────────────────────────┐   │
│  │             Outbound Adapters (Output)                │   │
│  │      PostgreSQL Repository &amp;amp; Persistence              │   │
│  └───────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Layer Interaction Flow
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;REST Request → Controller → Application Service → Domain Logic → Repository → Database&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The dependency rule: &lt;strong&gt;Dependencies point inward&lt;/strong&gt; (Infrastructure → Application → Domain)&lt;/p&gt;

&lt;h2&gt;
  
  
  🎯 What is Hexagonal Architecture?
&lt;/h2&gt;

&lt;p&gt;Hexagonal Architecture (coined by Alistair Cockburn) is a software design pattern that creates loosely coupled application components.&lt;/p&gt;

&lt;h3&gt;
  
  
  Core Concepts
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Domain (Core/Hexagon)&lt;/strong&gt;: The business logic lives here, completely isolated from external concerns&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pure business rules&lt;/li&gt;
&lt;li&gt;Domain models&lt;/li&gt;
&lt;li&gt;Domain exceptions&lt;/li&gt;
&lt;li&gt;No framework dependencies&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Ports&lt;/strong&gt;: Interfaces that define contracts&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Input Ports&lt;/strong&gt;: Define use cases (e.g., &lt;code&gt;TaskService&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Output Ports&lt;/strong&gt;: Define what the domain needs from external systems (e.g., &lt;code&gt;TaskRepository&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Adapters&lt;/strong&gt;: Implementations that connect to the outside world&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Inbound/Primary Adapters&lt;/strong&gt;: Drive the application (e.g., REST controllers, CLI)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Outbound/Secondary Adapters&lt;/strong&gt;: Driven by the application (e.g., database repositories, external APIs)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Why "Hexagonal"?
&lt;/h3&gt;

&lt;p&gt;The hexagon shape symbolizes that the architecture can have &lt;strong&gt;multiple adapters&lt;/strong&gt; on each side - it's not limited to just one input or output method.&lt;/p&gt;

&lt;h2&gt;
  
  
  📁 Project Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dev.hazegh.demo_hexagonal_architecture/
│
├── domain/                                    # 🔵 CORE DOMAIN (No external dependencies)
│   ├── model/
│   │   ├── Task.java                         # Domain entity with business logic
│   │   └── TaskStatus.java                   # Enum (TODO, IN_PROGRESS, DONE)
│   ├── exception/
│   │   ├── TaskNotFoundException.java
│   │   └── InvalidTaskStateException.java
│   └── port/
│       └── output/
│           └── TaskRepository.java           # Output port interface
│
├── application/                               # 🟢 APPLICATION LAYER
│   ├── port/
│   │   └── input/
│   │       └── TaskService.java              # Input port (use case interface)
│   └── service/
│       └── TaskServiceImpl.java              # Use case implementation
│
└── infrastructure/                            # 🟠 INFRASTRUCTURE LAYER
    └── adapter/
        ├── input/
        │   └── rest/
        │       ├── TaskController.java       # REST API adapter
        │       ├── dto/
        │       │   ├── CreateTaskRequest.java
        │       │   ├── UpdateTaskRequest.java
        │       │   ├── ChangeStatusRequest.java
        │       │   └── TaskResponse.java
        │       └── exception/
        │           ├── GlobalExceptionHandler.java
        │           └── ErrorResponse.java
        └── output/
            └── persistence/
                ├── entity/
                │   └── TaskJpaEntity.java    # JPA entity (infrastructure concern)
                ├── mapper/
                │   └── TaskMapper.java       # Maps between domain and JPA
                ├── TaskJpaRepository.java    # Spring Data JPA interface
                └── TaskRepositoryAdapter.java # Implements domain port
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🔑 Key Design Principles
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Dependency Inversion Principle
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;High-level modules (domain) don't depend on low-level modules (infrastructure)&lt;/li&gt;
&lt;li&gt;Both depend on abstractions (ports/interfaces)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Separation of Concerns
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Domain&lt;/strong&gt;: Business rules (e.g., "A completed task cannot go back to TODO")&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application&lt;/strong&gt;: Orchestration (e.g., "Find task, change status, save task")&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure&lt;/strong&gt;: Technical details (e.g., REST, JPA, PostgreSQL)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Testability
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Domain logic can be tested without any frameworks&lt;/li&gt;
&lt;li&gt;Application logic can be tested with mocked repositories&lt;/li&gt;
&lt;li&gt;Each layer can be tested independently&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Flexibility
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Easy to swap adapters (e.g., PostgreSQL → MongoDB, REST → GraphQL)&lt;/li&gt;
&lt;li&gt;Domain remains unchanged when infrastructure changes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🛠️ Technologies Used
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Java 21&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spring Boot 4.0.1&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Spring Web (REST API)&lt;/li&gt;
&lt;li&gt;Spring Data JPA (Persistence)&lt;/li&gt;
&lt;li&gt;Spring Validation (Bean validation)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;PostgreSQL&lt;/strong&gt; (Production database)&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;H2&lt;/strong&gt; (Test database)&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Lombok&lt;/strong&gt; (Reduce boilerplate)&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Maven&lt;/strong&gt; (Build tool)&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Docker &amp;amp; Docker Compose&lt;/strong&gt; (Containerization)&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;JUnit 5 &amp;amp; Mockito&lt;/strong&gt; (Testing)&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  🚀 Getting Started
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Java 21 or higher&lt;/li&gt;
&lt;li&gt;Docker and Docker Compose&lt;/li&gt;
&lt;li&gt;Maven 3.9+ (or use the included Maven wrapper)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1. Clone the Repository
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/rezahazegh/demo-hexagonal-architecture
&lt;span class="nb"&gt;cd &lt;/span&gt;demo-hexagonal-architecture
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Start PostgreSQL Database
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will start PostgreSQL on &lt;code&gt;localhost:5432&lt;/code&gt; with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Database: &lt;code&gt;taskdb&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Username: &lt;code&gt;taskuser&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Password: &lt;code&gt;taskpass&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Run the Application
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Using Maven Wrapper (Recommended):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./mvnw spring-boot:run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Or using Maven:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn spring-boot:run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application will start on &lt;code&gt;http://localhost:8080&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Verify the Application
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:8080/api/tasks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should receive an empty array &lt;code&gt;[]&lt;/code&gt; (no tasks yet).&lt;/p&gt;

&lt;h2&gt;
  
  
  📚 API Documentation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Base URL
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost:8080/api/tasks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Endpoints
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Create a Task
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;POST /api/tasks
Content-Type: application/json

&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"title"&lt;/span&gt;: &lt;span class="s2"&gt;"Learn Hexagonal Architecture"&lt;/span&gt;,
  &lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"Study the concepts and implement a demo project"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

Response: 201 Created
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"id"&lt;/span&gt;: &lt;span class="s2"&gt;"550e8400-e29b-41d4-a716-446655440000"&lt;/span&gt;,
  &lt;span class="s2"&gt;"title"&lt;/span&gt;: &lt;span class="s2"&gt;"Learn Hexagonal Architecture"&lt;/span&gt;,
  &lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"Study the concepts and implement a demo project"&lt;/span&gt;,
  &lt;span class="s2"&gt;"status"&lt;/span&gt;: &lt;span class="s2"&gt;"TODO"&lt;/span&gt;,
  &lt;span class="s2"&gt;"createdAt"&lt;/span&gt;: &lt;span class="s2"&gt;"2025-12-26T10:00:00"&lt;/span&gt;,
  &lt;span class="s2"&gt;"updatedAt"&lt;/span&gt;: &lt;span class="s2"&gt;"2025-12-26T10:00:00"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Get All Tasks
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;GET /api/tasks

Response: 200 OK
&lt;span class="o"&gt;[&lt;/span&gt;
  &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"id"&lt;/span&gt;: &lt;span class="s2"&gt;"550e8400-e29b-41d4-a716-446655440000"&lt;/span&gt;,
    &lt;span class="s2"&gt;"title"&lt;/span&gt;: &lt;span class="s2"&gt;"Learn Hexagonal Architecture"&lt;/span&gt;,
    &lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"Study the concepts and implement a demo project"&lt;/span&gt;,
    &lt;span class="s2"&gt;"status"&lt;/span&gt;: &lt;span class="s2"&gt;"TODO"&lt;/span&gt;,
    &lt;span class="s2"&gt;"createdAt"&lt;/span&gt;: &lt;span class="s2"&gt;"2025-12-26T10:00:00"&lt;/span&gt;,
    &lt;span class="s2"&gt;"updatedAt"&lt;/span&gt;: &lt;span class="s2"&gt;"2025-12-26T10:00:00"&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Get Task by ID
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;GET /api/tasks/&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;

Response: 200 OK
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"id"&lt;/span&gt;: &lt;span class="s2"&gt;"550e8400-e29b-41d4-a716-446655440000"&lt;/span&gt;,
  &lt;span class="s2"&gt;"title"&lt;/span&gt;: &lt;span class="s2"&gt;"Learn Hexagonal Architecture"&lt;/span&gt;,
  &lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"Study the concepts and implement a demo project"&lt;/span&gt;,
  &lt;span class="s2"&gt;"status"&lt;/span&gt;: &lt;span class="s2"&gt;"TODO"&lt;/span&gt;,
  &lt;span class="s2"&gt;"createdAt"&lt;/span&gt;: &lt;span class="s2"&gt;"2025-12-26T10:00:00"&lt;/span&gt;,
  &lt;span class="s2"&gt;"updatedAt"&lt;/span&gt;: &lt;span class="s2"&gt;"2025-12-26T10:00:00"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4. Update Task
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;PUT /api/tasks/&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
Content-Type: application/json

&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"title"&lt;/span&gt;: &lt;span class="s2"&gt;"Master Hexagonal Architecture"&lt;/span&gt;,
  &lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"Deep dive into advanced concepts"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

Response: 200 OK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  5. Change Task Status
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;PATCH /api/tasks/&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;/status
Content-Type: application/json

&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"status"&lt;/span&gt;: &lt;span class="s2"&gt;"IN_PROGRESS"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

Response: 200 OK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Valid status transitions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;TODO&lt;/code&gt; → &lt;code&gt;IN_PROGRESS&lt;/code&gt; ✅&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;TODO&lt;/code&gt; → &lt;code&gt;DONE&lt;/code&gt; ✅&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;IN_PROGRESS&lt;/code&gt; → &lt;code&gt;DONE&lt;/code&gt; ✅&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DONE&lt;/code&gt; → &lt;code&gt;TODO&lt;/code&gt; ❌ (Business rule violation)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DONE&lt;/code&gt; → &lt;code&gt;IN_PROGRESS&lt;/code&gt; ❌ (Business rule violation)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  6. Delete Task
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;DELETE /api/tasks/&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;

Response: 204 No Content
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Error Responses
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Validation Error
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-12-26T10:00:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Validation Failed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Invalid input data"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/api/tasks"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"validationErrors"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Title is required"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Not Found
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-12-26T10:00:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Not Found"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Task not found with id: 550e8400-e29b-41d4-a716-446655440000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/api/tasks/550e8400-e29b-41d4-a716-446655440000"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Invalid State Transition
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-12-26T10:00:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bad Request"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Failed to change status: Cannot move a completed task back to TODO"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/api/tasks/550e8400-e29b-41d4-a716-446655440000/status"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧪 Testing
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Run All Tests
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./mvnw &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Test Structure
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Unit Tests
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Domain Tests&lt;/strong&gt; (&lt;code&gt;TaskTest.java&lt;/code&gt;): Test business logic in isolation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application Tests&lt;/strong&gt; (&lt;code&gt;TaskServiceImplTest.java&lt;/code&gt;): Test use cases with mocked dependencies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mapper Tests&lt;/strong&gt; (&lt;code&gt;TaskMapperTest.java&lt;/code&gt;): Test data transformations&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Integration Tests
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;REST API Tests&lt;/strong&gt; (&lt;code&gt;TaskControllerIntegrationTest.java&lt;/code&gt;): End-to-end API testing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repository Tests&lt;/strong&gt; (&lt;code&gt;TaskRepositoryAdapterTest.java&lt;/code&gt;): Database integration testing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Test Coverage
&lt;/h3&gt;

&lt;p&gt;The tests demonstrate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Business rule enforcement (e.g., status transition rules)&lt;/li&gt;
&lt;li&gt;✅ Validation handling&lt;/li&gt;
&lt;li&gt;✅ Error scenarios (not found, invalid state)&lt;/li&gt;
&lt;li&gt;✅ CRUD operations&lt;/li&gt;
&lt;li&gt;✅ Mapper bidirectional conversions&lt;/li&gt;
&lt;li&gt;✅ Repository persistence&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  💡 Benefits of This Architecture
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Independence from Frameworks&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The core business logic doesn't depend on Spring, JPA, or any framework&lt;/li&gt;
&lt;li&gt;Frameworks become implementation details&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Testability&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Domain logic can be tested without any infrastructure&lt;/li&gt;
&lt;li&gt;Easy to write unit tests with minimal setup&lt;/li&gt;
&lt;li&gt;Clear boundaries make mocking straightforward&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Flexibility&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Database change&lt;/strong&gt;: Swap PostgreSQL for MongoDB without touching domain/application&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API change&lt;/strong&gt;: Add GraphQL alongside REST without modifying business logic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add new adapters&lt;/strong&gt;: CLI, gRPC, message queue - all without changing the core&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Maintainability&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Clear separation makes code easier to understand&lt;/li&gt;
&lt;li&gt;Changes in one layer don't ripple through the entire application&lt;/li&gt;
&lt;li&gt;Each component has a single responsibility&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. &lt;strong&gt;Business Logic Protection&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Domain rules are explicit and enforced in one place&lt;/li&gt;
&lt;li&gt;No risk of bypassing business logic through different entry points&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6. &lt;strong&gt;Team Scalability&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Different teams can work on different layers independently&lt;/li&gt;
&lt;li&gt;Clear contracts (ports) reduce integration conflicts&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔄 Example: Swapping Adapters
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Current Setup
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;REST API (Inbound)&lt;/li&gt;
&lt;li&gt;PostgreSQL (Outbound)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Adding a New Adapter (e.g., CLI)
&lt;/h3&gt;

&lt;p&gt;You can add a CLI adapter without changing domain or application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TaskCliAdapter&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;CommandLineRunner&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;TaskService&lt;/span&gt; &lt;span class="n"&gt;taskService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Task&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;taskService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createTask&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CLI Task"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Created from CLI"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Created task: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Swapping Database (PostgreSQL → MongoDB)
&lt;/h3&gt;

&lt;p&gt;Just create a new adapter implementing &lt;code&gt;TaskRepository&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Repository&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MongoTaskRepository&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;TaskRepository&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;MongoTemplate&lt;/span&gt; &lt;span class="n"&gt;mongoTemplate&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// Implementation using MongoDB&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The domain and application layers remain unchanged!&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🐳 Docker Commands
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Start PostgreSQL&lt;/span&gt;
docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt;

&lt;span class="c"&gt;# Stop PostgreSQL&lt;/span&gt;
docker-compose down

&lt;span class="c"&gt;# View logs&lt;/span&gt;
docker-compose logs &lt;span class="nt"&gt;-f&lt;/span&gt; postgres

&lt;span class="c"&gt;# Clean up (removes volumes)&lt;/span&gt;
docker-compose down &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📝 Environment Variables
&lt;/h2&gt;

&lt;p&gt;Copy &lt;code&gt;.env.example&lt;/code&gt; to &lt;code&gt;.env&lt;/code&gt; and customize if needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Default values:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;POSTGRES_DB=taskdb&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;POSTGRES_USER=taskuser&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;POSTGRES_PASSWORD=taskpass&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;POSTGRES_PORT=5432&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📖 Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://alistair.cockburn.us/hexagonal-architecture/" rel="noopener noreferrer"&gt;Hexagonal Architecture by Alistair Cockburn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html" rel="noopener noreferrer"&gt;Clean Architecture by Robert C. Martin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://herbertograca.com/2017/09/14/ports-adapters-architecture/" rel="noopener noreferrer"&gt;Ports and Adapters Pattern&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Built with ❤️ to demonstrate Hexagonal Architecture principles&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>springboot</category>
      <category>java</category>
      <category>hexagonal</category>
    </item>
    <item>
      <title>Understanding Object-Relational Impedance Mismatch</title>
      <dc:creator>rezahazegh</dc:creator>
      <pubDate>Thu, 31 Oct 2024 09:38:27 +0000</pubDate>
      <link>https://dev.to/reza_sh/understanding-object-relational-impedance-mismatch-25pc</link>
      <guid>https://dev.to/reza_sh/understanding-object-relational-impedance-mismatch-25pc</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw2h843vegyw5f5b0agin.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw2h843vegyw5f5b0agin.png" alt="Understanding Object-Relational Impedance Mismatch" width="800" height="457"&gt;&lt;/a&gt;&lt;br&gt;
Object-relational impedance mismatch refers to the challenges that arise when you try to bridge the differences between object-oriented programming languages (which use object models) and relational databases. Here’s a breakdown of why this happens:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Data Structure Mismatch&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Object Model&lt;/strong&gt;: Organizes data in objects and classes, using attributes and methods that represent real-world entities. Objects may contain nested objects, hierarchies, and complex relationships.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Relational Database&lt;/strong&gt;: Organizes data in tables with rows and columns, following strict schemas. Relationships between entities are represented through foreign keys and join tables.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This structural difference makes it difficult to directly map objects to tables.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Inheritance&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Object Model&lt;/strong&gt;: Allows for inheritance, meaning that a class can inherit properties and behavior from another class.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Relational Database&lt;/strong&gt;: Lacks a straightforward way to represent inheritance. This typically requires extra tables or additional columns in relational models to mimic inheritance, complicating data design and retrieval.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Identity and References&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Object Model&lt;/strong&gt;: Uses direct object references, meaning an object has a pointer to another object, forming a web of interconnected instances.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Relational Database&lt;/strong&gt;: Uses foreign keys and joins to establish relationships, which requires querying and joining tables to retrieve related data.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Data Retrieval&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Object Model&lt;/strong&gt;: Can directly access related objects (e.g., &lt;code&gt;user.address.street&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Relational Database&lt;/strong&gt;: Requires SQL queries, often involving multiple joins, which can lead to complex query logic.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;CRUD Operations&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Object Model&lt;/strong&gt;: Can be less predictable when saved to a relational database due to cascades of complex relationships and updates, making transactional control challenging.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Relational Database&lt;/strong&gt;: Designed to handle CRUD operations but with simpler data models. Object-oriented models need ORMs (Object-Relational Mappers) to translate objects to tables and vice versa.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Solutions to Impedance Mismatch
&lt;/h3&gt;

&lt;p&gt;ORM (Object-Relational Mapping) frameworks like Hibernate (Java), SQLAlchemy (Python), and Entity Framework (.NET) help map objects to relational tables, providing an abstraction that simplifies CRUD operations.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Error handling in express.js</title>
      <dc:creator>rezahazegh</dc:creator>
      <pubDate>Wed, 25 Oct 2023 17:31:31 +0000</pubDate>
      <link>https://dev.to/reza_sh/error-handling-in-expressjs-28om</link>
      <guid>https://dev.to/reza_sh/error-handling-in-expressjs-28om</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;In this article, I used the code in the following repository:&lt;br&gt;
&lt;a href="https://github.com/rezahazegh/demo-express-error-handling"&gt;https://github.com/rezahazegh/demo-express-error-handling&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To demonstrate how express.js behaves regarding error handling by using some pretty straightforward examples. Then, I provided a solution to have cleaner syntax to handle errors.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hint&lt;/strong&gt;: express.js behavior is different for version 5 and above.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trail and Error
&lt;/h3&gt;

&lt;p&gt;The project includes some routes which show express behavior under different conditions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;/test&lt;/code&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We use it to check either app crashed or still working&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;/sync&lt;/code&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you call this route it throws an error from within a sync route handler.
&lt;/li&gt;
&lt;li&gt;if we call &lt;code&gt;test&lt;/code&gt; the app would work. So, express catches it automatically and, we don't need any extra action for sync handlers. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;/async-not-handled&lt;/code&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you call this route it throws an error from within an async route handler which is not handled.
&lt;/li&gt;
&lt;li&gt;If you call &lt;code&gt;test&lt;/code&gt; the app won't work and, you will see it already crashed.&lt;/li&gt;
&lt;li&gt;So, we need to somehow handle errors for async handlers. we show how to do that on the next ones.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;/async-handled-regular&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you call this route it throws an error from within an async route handler which is handled using try/catch.&lt;/li&gt;
&lt;li&gt;The point is you should pass error to &lt;code&gt;next&lt;/code&gt; function.&lt;/li&gt;
&lt;li&gt;Now, if we call &lt;code&gt;test&lt;/code&gt; the app would work.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Magic solution
&lt;/h3&gt;

&lt;p&gt;The following solution helps you to get rid of try/catch in your handlers.  &lt;/p&gt;

&lt;p&gt;Functions in javascript are first class citizens: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you can pass a function as a parameter to another one. &lt;/li&gt;
&lt;li&gt;Also, you can return a function as a return value.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We are going to use these features to design our solution.  &lt;/p&gt;

&lt;p&gt;&lt;code&gt;handler&lt;/code&gt; function helps us to extract try/catch from our handlers. It takes our handler as a parameter and wrap it in a try/catch in a new function. Then return the new function.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;/async-handled-using-handler&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;If you call this route it throws an error from within an async route handler which is handled using &lt;code&gt;handler&lt;/code&gt; function.&lt;/li&gt;
&lt;li&gt;Now, if we call &lt;code&gt;test&lt;/code&gt; the app would work.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>GraphQL server demo via express and @apollo/server</title>
      <dc:creator>rezahazegh</dc:creator>
      <pubDate>Wed, 18 Jan 2023 16:10:20 +0000</pubDate>
      <link>https://dev.to/reza_sh/graphql-server-demo-via-express-and-apolloserver-4kjd</link>
      <guid>https://dev.to/reza_sh/graphql-server-demo-via-express-and-apolloserver-4kjd</guid>
      <description>&lt;p&gt;The following repository demonstrates a simple GraphQL server app via express and @apollo/server.&lt;br&gt;
&lt;a href="https://github.com/rezahazegh/demo-apollo-server"&gt;https://github.com/rezahazegh/demo-apollo-server&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Description
&lt;/h2&gt;

&lt;p&gt;This project contains &lt;code&gt;Course&lt;/code&gt; and &lt;code&gt;Teacher&lt;/code&gt; entities, It provides create, update and delete for them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Entities relation&lt;/strong&gt;: Every course would have a teacher.&lt;/p&gt;

&lt;h2&gt;
  
  
  Directory Description
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;models&lt;/code&gt;: It includes required mongoose models to store entities in MongoDB&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;schema&lt;/code&gt;: it include GraphQL related stuff

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;types&lt;/code&gt;: It includes types, something like dto in REST API&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;resolvers&lt;/code&gt;: It include resolvers, something like route handlers in REST API&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Project Setup
&lt;/h2&gt;

&lt;p&gt;Run &lt;code&gt;docker compose up -d&lt;/code&gt; to setup MongoDB via docker&lt;/p&gt;

&lt;p&gt;Run app and open &lt;code&gt;localhost:4000&lt;/code&gt; to reach out to  Apollo Sandbox (An in-browser tool for writing, validating, and testing GraphQL queries)&lt;/p&gt;

&lt;h2&gt;
  
  
  Sample Requests
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create, Read and Delete Teacher
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mutation {
  addTeacher(name: "Peter Parker", email: "spiderman@gmail.com", phone: "855-465-2386") {
    id
    name
    email
    phone
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  teachers {
    id,
    name
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  teacher(id: "63c421e024a2dcb1e5dcdce6") {
    id,
    name
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mutation {
  deleteTeacher(id: "63c421e024a2dcb1e5dcdce6") {
    id,
    name
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create, Read, Update and Delete Course
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mutation {
  addCourse(name: "GraphQL by Spider-Man", description: "This is the project description", status: new, teacherId: "63c424b724a2dcb1e5dcdcef") {
   name
   description
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  courses {
    id,
    name,
    status
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  course(id: "63c4252c24a2dcb1e5dcdcf1") {
    id,
    name,
    status
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mutation {
  updateCourse(id: "63c4252c24a2dcb1e5dcdcf1", status: completed) {
   name
   status
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mutation {
  deleteCourse(id: "63c4252c24a2dcb1e5dcdcf1") {
    id
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>GraphQL server demo via express and express-graphql</title>
      <dc:creator>rezahazegh</dc:creator>
      <pubDate>Sun, 15 Jan 2023 16:39:16 +0000</pubDate>
      <link>https://dev.to/reza_sh/graphql-server-demo-via-express-and-express-graphql-4f</link>
      <guid>https://dev.to/reza_sh/graphql-server-demo-via-express-and-express-graphql-4f</guid>
      <description>&lt;p&gt;The following repository demonstrates a simple GraphQL server app via express and express-graphql.&lt;br&gt;
&lt;a href="https://github.com/rezahazegh/demo-express-graphql" rel="noopener noreferrer"&gt;https://github.com/rezahazegh/demo-express-graphql&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Description
&lt;/h2&gt;

&lt;p&gt;This project contains &lt;code&gt;Course&lt;/code&gt; and &lt;code&gt;Teacher&lt;/code&gt; entities, It provides create, update and delete for them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Entities relation&lt;/strong&gt;: Every course would have a teacher.&lt;/p&gt;

&lt;h2&gt;
  
  
  Directory Description
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;models&lt;/code&gt;: It includes required mongoose models to store entities in MongoDB&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;schema&lt;/code&gt;: it include GraphQL related stuff

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;types&lt;/code&gt;: It includes types, something like dto in REST API&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;resolvers&lt;/code&gt;: It include resolvers, something like route handlers in REST API&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Project Setup
&lt;/h2&gt;

&lt;p&gt;Run &lt;code&gt;docker compose up -d&lt;/code&gt; to setup MongoDB via docker&lt;/p&gt;

&lt;p&gt;Run app and open &lt;code&gt;localhost:3000/graphql&lt;/code&gt; to reach out to GraphiQL (An in-browser tool for writing, validating, and testing GraphQL queries)&lt;/p&gt;

&lt;h2&gt;
  
  
  Sample Requests
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create, Read and Delete Teacher
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mutation {
  addTeacher(name: "Peter Parker", email: "spiderman@gmail.com", phone: "855-465-2386") {
    id
    name
    email
    phone
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  teachers {
    id,
    name
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  teacher(id: "63c421e024a2dcb1e5dcdce6") {
    id,
    name
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mutation {
  deleteTeacher(id: "63c421e024a2dcb1e5dcdce6") {
    id,
    name
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create, Read, Update and Delete Course
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mutation {
  addCourse(name: "GraphQL by Spider-Man", description: "This is the project description", status: new, teacherId: "63c424b724a2dcb1e5dcdcef") {
   name
   description
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  courses {
    id,
    name,
    status
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  course(id: "63c4252c24a2dcb1e5dcdcf1") {
    id,
    name,
    status
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mutation {
  updateCourse(id: "63c4252c24a2dcb1e5dcdcf1", status: completed) {
   name
   status
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mutation {
  deleteCourse(id: "63c4252c24a2dcb1e5dcdcf1") {
    id
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>ai</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Nest.js integration with Kafka</title>
      <dc:creator>rezahazegh</dc:creator>
      <pubDate>Sun, 08 Jan 2023 17:38:02 +0000</pubDate>
      <link>https://dev.to/reza_sh/nestjs-integration-with-kafka-2cbi</link>
      <guid>https://dev.to/reza_sh/nestjs-integration-with-kafka-2cbi</guid>
      <description>&lt;p&gt;The following repository demonstrates a simple microservice app which integrates NestJS with Apache Kafka.&lt;br&gt;
&lt;a href="https://github.com/rezahazegh/kafka-nestjs" rel="noopener noreferrer"&gt;https://github.com/rezahazegh/kafka-nestjs&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Project Description
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Producer receives two number via &lt;code&gt;REST API&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Producer sends numbers to kafka &lt;code&gt;sum&lt;/code&gt; topic.&lt;/li&gt;
&lt;li&gt;Consumer subscribes to &lt;code&gt;sum&lt;/code&gt; topic and receives numbers and returns sum of numbers.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Directory Description
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;infra&lt;/code&gt; directory includes &lt;code&gt;docker-compose&lt;/code&gt; to setup kafka&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;producer&lt;/code&gt; directory includes a projects which send payloads to kafka&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;consumer&lt;/code&gt; directory includes a project which receives payloads from kafka&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Run and Test
&lt;/h2&gt;

&lt;p&gt;After setup kafka and running &lt;code&gt;producer&lt;/code&gt; and &lt;code&gt;consumer&lt;/code&gt; you can call &lt;code&gt;localhost:3000&lt;/code&gt; by &lt;code&gt;POST&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sample Payload:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "num1": 7,
    "num2": 9
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sample Response:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sum of 7 and 9 is: 16
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  List of Kafka Topics
&lt;/h2&gt;

&lt;p&gt;By running &lt;code&gt;npm run topic-list&lt;/code&gt; inside &lt;code&gt;infra&lt;/code&gt; directory, you can see list of kafka topics.&lt;/p&gt;

&lt;p&gt;Sample Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;__consumer_offsets
sum
sum.reply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>showdev</category>
      <category>webdev</category>
      <category>website</category>
    </item>
  </channel>
</rss>
