Skip to content

ubaidillahhf/hexagonal-boilerplate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

3 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Hexagonal Architecture Boilerplate

Go Version License PRs Welcome

A comprehensive, production-ready Go boilerplate implementing Hexagonal Architecture (Ports & Adapters) with best practices for building scalable, maintainable microservices.

πŸ“‹ Table of Contents

πŸš€ Quick Start

# Clone the repository
git clone https://github.com/ubaidillahhf/hexagonal-boilerplate.git
cd hexagonal-boilerplate

# Set up environment
cp .env.example .env

# Start infrastructure (MongoDB, Redis, RabbitMQ, Jaeger)
docker-compose up -d

# Run the application
go run cmd/main.go

The server will start on http://localhost:8080

Test it:

curl http://localhost:8080/health

πŸ—οΈ Architecture

This boilerplate follows true Hexagonal Architecture principles with clear separation of concerns:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Primary Adapters                          β”‚
β”‚              (REST API, gRPC, CLI, etc.)                     β”‚
β”‚                                                               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
β”‚  β”‚   HTTP      β”‚  β”‚   gRPC      β”‚  β”‚     CLI     β”‚         β”‚
β”‚  β”‚  Handlers   β”‚  β”‚  Handlers   β”‚  β”‚  Commands   β”‚         β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚                 β”‚                 β”‚
          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                            β–Ό
          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
          β”‚      Application Layer (Ports)       β”‚
          β”‚                                      β”‚
          β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
          β”‚  β”‚   Input Ports (Use Cases)      β”‚ β”‚
          β”‚  β”‚   - OrderUseCase               β”‚ β”‚
          β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
          β”‚               β”‚                      β”‚
          β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
          β”‚  β”‚   Use Case Implementations     β”‚ β”‚
          β”‚  β”‚   (Application Services)       β”‚ β”‚
          β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
          β”‚               β”‚                      β”‚
          β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
          β”‚  β”‚   Output Ports (Interfaces)    β”‚ β”‚
          β”‚  β”‚   - OrderRepository            β”‚ β”‚
          β”‚  β”‚   - CacheRepository            β”‚ β”‚
          β”‚  β”‚   - EventPublisher             β”‚ β”‚
          β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          β”‚
          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
          β”‚         Domain Layer                 β”‚
          β”‚                                      β”‚
          β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
          β”‚  β”‚   Entities & Value Objects     β”‚ β”‚
          β”‚  β”‚   - Order, OrderItem           β”‚ β”‚
          β”‚  β”‚   - Money (Value Object)       β”‚ β”‚
          β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
          β”‚                                      β”‚
          β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
          β”‚  β”‚   Domain Errors                β”‚ β”‚
          β”‚  β”‚   - Enhanced error tracking    β”‚ β”‚
          β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          β–²
                          β”‚
          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
          β”‚      Secondary Adapters              β”‚
          β”‚                                      β”‚
          β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
          β”‚  β”‚ MongoDB  β”‚  β”‚  Redis   β”‚         β”‚
          β”‚  β”‚Repositoryβ”‚  β”‚  Cache   β”‚         β”‚
          β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚
          β”‚                                      β”‚
          β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
          β”‚  β”‚RabbitMQ  β”‚  β”‚ Feature  β”‚         β”‚
          β”‚  β”‚Publisher β”‚  β”‚  Flags   β”‚         β”‚
          β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚
          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

✨ Features

Core Architecture

  • βœ… Pure Hexagonal Architecture - True ports & adapters pattern
  • βœ… SOLID Principles - Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, Dependency Inversion
  • βœ… Domain-Driven Design - Rich domain models with business logic
  • βœ… Dependency Injection - Clean dependency management
  • βœ… Protocol Agnostic - Domain layer independent of HTTP/gRPC

Data & Messaging

  • βœ… MongoDB - Document database with optimistic locking
  • βœ… Redis - Caching with distributed locks
  • βœ… RabbitMQ - Event-driven messaging with auto-reconnection
  • βœ… Transaction Manager - Database-agnostic transaction abstraction (PostgreSQL, MongoDB, Elasticsearch)
  • βœ… ACID Transactions - Optimistic locking for concurrency control

Observability

  • βœ… OpenTelemetry Tracing - Distributed tracing with Jaeger
  • βœ… Structured Logging - Zap logger with context propagation
  • βœ… Error Tracking - Enhanced error handling with stack traces
  • βœ… Health Checks - Readiness and liveness endpoints

Performance & Reliability

  • βœ… Race Condition Prevention - Distributed locks and optimistic locking
  • βœ… Rate Limiting - Redis-backed rate limiter
  • βœ… Connection Pooling - Optimized database connections
  • βœ… Graceful Shutdown - Clean resource cleanup
  • βœ… Circuit Breaker Ready - Resilient external service calls

Developer Experience

  • βœ… Feature Flags - Runtime feature toggling
  • βœ… Hot Reload Ready - Environment-based configuration
  • βœ… Docker Compose - Local development environment
  • βœ… Makefile - Common development tasks
  • βœ… Clean Code - Well-documented and maintainable

πŸ“ Project Structure

hexagonal-boilerplate/
β”œβ”€β”€ cmd/
β”‚   └── main.go                          # Application entry point
β”‚
β”œβ”€β”€ internal/
β”‚   β”œβ”€β”€ domain/                          # Domain Layer (Core Business Logic)
β”‚   β”‚   β”œβ”€β”€ entity/                      # Domain entities
β”‚   β”‚   β”‚   └── order.go                 # Order aggregate with business rules
β”‚   β”‚   β”œβ”€β”€ valueobject/                 # Value objects
β”‚   β”‚   β”‚   └── money.go                 # Money value object
β”‚   β”‚   └── error/                       # Domain errors
β”‚   β”‚       └── error.go                 # Enhanced error with stack trace
β”‚   β”‚
β”‚   β”œβ”€β”€ application/                     # Application Layer (Use Cases)
β”‚   β”‚   β”œβ”€β”€ port/
β”‚   β”‚   β”‚   β”œβ”€β”€ input/                   # Input ports (use case interfaces)
β”‚   β”‚   β”‚   β”‚   └── order_usecase.go
β”‚   β”‚   β”‚   └── output/                  # Output ports (repository interfaces)
β”‚   β”‚   β”‚       β”œβ”€β”€ order_repository.go
β”‚   β”‚   β”‚       β”œβ”€β”€ cache_repository.go
β”‚   β”‚   β”‚       β”œβ”€β”€ event_publisher.go
β”‚   β”‚   β”‚       β”œβ”€β”€ feature_flag.go
β”‚   β”‚   β”‚       β”œβ”€β”€ logger.go            # Logger abstraction
β”‚   β”‚   β”‚       β”œβ”€β”€ tracer.go            # Tracer abstraction
β”‚   β”‚   β”‚       └── transaction_manager.go # Transaction abstraction
β”‚   β”‚   └── service/                     # Use case implementations
β”‚   β”‚       β”œβ”€β”€ order_service.go         # Order business logic
β”‚   β”‚       └── observability_helper.go  # Tracing & logging helpers
β”‚   β”‚
β”‚   └── infrastructure/                  # Infrastructure Layer (Adapters)
β”‚       β”œβ”€β”€ adapter/
β”‚       β”‚   β”œβ”€β”€ primary/                 # Inbound adapters
β”‚       β”‚   β”‚   └── rest/
β”‚       β”‚   β”‚       β”œβ”€β”€ handler/         # HTTP handlers
β”‚       β”‚   β”‚       β”œβ”€β”€ middleware/      # Rate limiting, tracing, recovery
β”‚       β”‚   β”‚       └── router.go        # Route definitions
β”‚       β”‚   β”‚
β”‚       β”‚   └── secondary/               # Outbound adapters
β”‚       β”‚       β”œβ”€β”€ persistence/
β”‚       β”‚       β”‚   β”œβ”€β”€ mongodb/         # MongoDB repository
β”‚       β”‚       β”‚   β”œβ”€β”€ postgres/        # PostgreSQL repository
β”‚       β”‚       β”‚   └── elasticsearch/   # Elasticsearch repository
β”‚       β”‚       β”œβ”€β”€ cache/               # Redis/Valkey cache
β”‚       β”‚       β”œβ”€β”€ messaging/           # RabbitMQ/NATS publisher
β”‚       β”‚       └── feature/             # Feature flag service
β”‚       β”‚
β”‚       β”œβ”€β”€ config/                      # Configuration
β”‚       β”œβ”€β”€ database/                    # Database clients
β”‚       β”œβ”€β”€ observability/               # Logging & tracing adapters
β”‚       β”‚   β”œβ”€β”€ zap_logger.go           # Zap logger adapter
β”‚       β”‚   └── otel_tracer.go          # OpenTelemetry tracer adapter
β”‚       └── transaction/                 # Transaction manager adapters
β”‚           β”œβ”€β”€ postgres_transaction_manager.go
β”‚           β”œβ”€β”€ mongodb_transaction_manager.go
β”‚           └── noop_transaction_manager.go
β”‚
β”œβ”€β”€ docker-compose.yml                   # Local infrastructure
β”œβ”€β”€ Makefile                             # Development commands
β”œβ”€β”€ go.mod                               # Go dependencies
└── .env.example                         # Environment variables template

πŸš€ Getting Started

Prerequisites

  • Go 1.21+
  • Docker & Docker Compose
  • Make (optional)

Installation

  1. Clone the repository:
git clone https://github.com/ubaidillahhf/hexagonal-boilerplate.git
cd hexagonal-boilerplate
  1. Set up environment:
cp .env.example .env
# Edit .env with your configuration
  1. Start infrastructure services:
make docker-up
# or
docker-compose up -d
  1. Install dependencies:
make deps
# or
go mod download
  1. Run the application:
make run
# or
go run cmd/main.go

The server will start on http://localhost:8080

πŸ“š API Documentation

Health Check

curl http://localhost:8080/health

Create Order

curl -X POST http://localhost:8080/api/v1/orders \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "customer-123",
    "items": [
      {
        "product_id": "product-456",
        "quantity": 2,
        "price": 29.99
      }
    ]
  }'

Get Order

curl http://localhost:8080/api/v1/orders/{order_id}

List Orders

curl "http://localhost:8080/api/v1/orders?page=1&limit=20&customer_id=customer-123"

Confirm Order

curl -X POST http://localhost:8080/api/v1/orders/{order_id}/confirm

Process Payment

curl -X POST http://localhost:8080/api/v1/orders/{order_id}/payment

Cancel Order

curl -X POST http://localhost:8080/api/v1/orders/{order_id}/cancel

πŸ”§ Configuration

All configuration is managed through environment variables. See .env.example for available options:

  • Server: Port, timeouts, shutdown timeout
  • MongoDB: Connection URI, pool sizes
  • Redis: Address, pool configuration
  • RabbitMQ: Connection URL, exchange, queue
  • Feature Flags: Enable/disable features at runtime
  • Rate Limiting: Requests per window
  • Tracing: Jaeger endpoint, sampling
  • Logging: Level (debug/info/warn/error), format (json/console)

🎯 Best Practices Implemented

1. Enhanced Error Handling

// Domain errors with stack traces and context
err := domainErr.Wrapf(
    domainErr.ErrCodeNotFound, 
    originalErr, 
    "order not found: %s", 
    orderID,
)
err.WithField("customer_id", customerID)

2. Race Condition Prevention

// Distributed locks with Redis
lockKey := fmt.Sprintf("lock:order:%s", orderID)
acquired, err := cache.SetNX(ctx, lockKey, "1", 10*time.Second)

// Optimistic locking with version control
err := repo.UpdateWithOptimisticLock(ctx, order, expectedVersion)

3. Distributed Tracing

ctx, span := tracer.Start(ctx, "OrderService.CreateOrder")
defer span.End()

span.SetAttributes(
    attribute.String("order_id", order.ID),
    attribute.Float64("amount", order.TotalAmount),
)

4. Transaction Management

// Database-agnostic transaction abstraction
// Application layer controls transaction boundaries
err := txManager.ExecuteInTransaction(ctx, func(txCtx context.Context) error {
    if err := orderRepo.Create(txCtx, order); err != nil {
        return err
    }
    if err := inventoryRepo.Reserve(txCtx, items); err != nil {
        return err
    }
    return nil // Auto-commit on success, auto-rollback on error
})

// Works with PostgreSQL, MongoDB, or no-op for Elasticsearch
// No database-specific code in application layer

5. Feature Flags

if !featureFlag.IsEnabled(ctx, FeatureOrderCreation) {
    return domainErr.ErrFeatureDisabled
}

6. Rate Limiting

// Redis-backed rate limiter per IP
// Configured via RATE_LIMIT_REQUESTS and RATE_LIMIT_WINDOW

7. Graceful Shutdown

// Coordinated shutdown with timeout
// Closes HTTP server, databases, message brokers cleanly

πŸ§ͺ Testing

# Run tests
make test

# Run tests with coverage
make test-coverage

# Run with race detector
go test -race ./...

πŸ“Š Observability

Jaeger UI

Access distributed traces at: http://localhost:16686

RabbitMQ Management

Access RabbitMQ console at: http://localhost:15672

  • Username: guest
  • Password: guest

Logs

Structured JSON logs with trace IDs for correlation:

{
  "level": "info",
  "timestamp": "2024-03-12T08:00:00Z",
  "caller": "service/order_service.go:45",
  "message": "Order created successfully",
  "order_id": "550e8400-e29b-41d4-a716-446655440000",
  "customer_id": "customer-123",
  "total_amount": 59.98,
  "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}

πŸ” SOLID Principles

  • Single Responsibility: Each layer has one reason to change
  • Open/Closed: Extend behavior via interfaces, not modification
  • Liskov Substitution: Implementations are interchangeable
  • Interface Segregation: Small, focused interfaces
  • Dependency Inversion: Depend on abstractions, not concretions

🎨 Design Patterns

  • Hexagonal Architecture (Ports & Adapters)
  • Repository Pattern (Data access abstraction)
  • Transaction Manager Pattern (Database-agnostic transaction control)
  • Dependency Injection (Loose coupling)
  • Factory Pattern (Object creation)
  • Strategy Pattern (Feature flags)
  • Observer Pattern (Event publishing)
  • Adapter Pattern (Logger, Tracer, Transaction abstractions)

πŸ“ˆ Performance Optimizations

  • Connection pooling for MongoDB and Redis
  • Caching with TTL and invalidation
  • Optimistic locking for minimal blocking
  • Efficient JSON serialization
  • Context-aware timeouts
  • Resource cleanup on shutdown

πŸ› οΈ Development Commands

make help          # Show all available commands
make build         # Build the application
make run           # Run the application
make test          # Run tests
make test-coverage # Run tests with coverage
make clean         # Clean build artifacts
make docker-up     # Start Docker services
make docker-down   # Stop Docker services
make docker-logs   # View Docker logs
make lint          # Run linter
make deps          # Download dependencies

πŸ› οΈ Alternative Adapters (Plug & Play)

This boilerplate includes multiple adapter implementations for each infrastructure component, demonstrating the true power of Hexagonal Architecture. Switch adapters without changing your domain logic!

Available Adapters

Component Default Alternatives Switch Guide
HTTP Framework Fiber Echo Guide
Cache Redis Valkey Guide
Message Broker RabbitMQ NATS Guide
Database MongoDB PostgreSQL, Elasticsearch Guide

Quick Switch Example

From: Fiber + MongoDB + Redis + RabbitMQ
To: Echo + PostgreSQL + Valkey + NATS

Just update cmd/main.go dependency injection - domain layer stays unchanged!

// Before
import "github.com/ubaidillahhf/hexagonal-boilerplate/internal/infrastructure/adapter/primary/rest"
app := rest.NewRouter(...)

// After
import echoAdapter "github.com/ubaidillahhf/hexagonal-boilerplate/internal/infrastructure/adapter/primary/echo"
app := echoAdapter.NewRouter(...)

πŸ“š Documentation

Why Multiple Adapters?

βœ… Demonstrates Hexagonal Architecture - Shows true adapter swapping
βœ… Technology Freedom - Choose the best tool for your needs
βœ… Migration Path - Easy to switch as requirements evolve
βœ… Learning Resource - See different implementations of same interface

πŸ”„ Extending the Boilerplate

Adding a New Entity

  1. Create entity in internal/domain/entity/
  2. Define repository interface in internal/application/port/output/
  3. Implement repository in internal/infrastructure/adapter/secondary/persistence/
  4. Create use case interface in internal/application/port/input/
  5. Implement use case in internal/application/service/
  6. Create HTTP handler in internal/infrastructure/adapter/primary/rest/handler/
  7. Register routes in internal/infrastructure/adapter/primary/rest/router.go

Adding a New Feature Flag

// 1. Define in output port
const FeatureNewFeature = "new_feature"

// 2. Add to .env
FEATURE_NEW_FEATURE_ENABLED=true

// 3. Use in service
if !s.featureFlag.IsEnabled(ctx, output.FeatureNewFeature) {
    return domainErr.ErrFeatureDisabled
}

πŸ“ License

MIT License - see the LICENSE file for details.

This boilerplate is free to use for both personal and commercial projects.

🀝 Contributing

Contributions are welcome! Here's how you can help:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Guidelines

  • Follow the existing code style and architecture patterns
  • Add tests for new features
  • Update documentation as needed
  • Ensure all tests pass before submitting PR

πŸ“ž Support

  • πŸ“– Documentation: Check the guidelines folder for detailed guides
  • πŸ’¬ Issues: Open an issue for bugs or feature requests
  • 🌟 Star: If you find this helpful, please star the repository!

πŸ™ Acknowledgments

This boilerplate is inspired by:

  • Hexagonal Architecture by Alistair Cockburn
  • Clean Architecture by Robert C. Martin (Uncle Bob)
  • Domain-Driven Design by Eric Evans
  • Best practices from companies like Uber, Netflix, Google, and Spotify

πŸ“š Related Resources


Built with ❀️ following Hexagonal Architecture best practices

⭐ If this boilerplate helps you, please consider giving it a star!

About

Creating hexagonal-boilerplate as a research, as someone who is familiar with clean architecture.

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors