KAL
By Ahmad Fikri Haikal

Mengenal Layered Architecture di Golang untuk Aplikasi yang Mudah Dikembangkan

Panduan memahami Layered Architecture di Golang, struktur folder, pembagian tanggung jawab, dan contoh implementasi sederhana.

Ilustrasi Arsitektur Aplikasi Golang

Ketika membangun aplikasi menggunakan Golang, salah satu tantangan terbesar adalah menjaga kode tetap rapi seiring bertambahnya fitur. Tanpa struktur yang jelas, kode akan sulit dipelajari, diuji, dan dikembangkan oleh tim.

Salah satu pendekatan yang banyak digunakan adalah Layered Architecture. Pola ini membagi aplikasi ke dalam beberapa lapisan (layer) yang memiliki tanggung jawab berbeda sehingga setiap bagian aplikasi dapat berkembang secara terpisah tanpa saling bergantung secara langsung.

Apa Itu Layered Architecture?

Layered Architecture adalah pola arsitektur perangkat lunak yang memisahkan aplikasi menjadi beberapa lapisan berdasarkan tanggung jawabnya.

Umumnya pada aplikasi Golang, layer yang digunakan terdiri dari:

  1. Handler / Controller Layer
  2. Service Layer
  3. Repository Layer
  4. Database Layer

Alur sederhananya:

Client Request

   Handler

   Service

 Repository

   Database

Berikut ilustrasi sederhana mengenai hubungan antar layer:

Diagram Layered Architecture Golang

Struktur Folder yang Umum Digunakan

Berikut contoh struktur project Layered Architecture pada Golang:

project/
├── cmd/
│   └── main.go
├── internal/
│   ├── handler/
│   │   └── user_handler.go
│   ├── service/
│   │   └── user_service.go
│   ├── repository/
│   │   └── user_repository.go
│   ├── model/
│   │   └── user.go
│   └── database/
│       └── mysql.go
├── go.mod
└── go.sum

Dengan struktur tersebut, setiap folder memiliki tanggung jawab yang jelas dan tidak saling bercampur.

Handler Layer

Handler bertugas menerima request dari client dan mengembalikan response.

Contoh sederhana:

type UserHandler struct {
    userService service.UserService
}

func (h *UserHandler) GetUsers(c *gin.Context) {
    users, err := h.userService.GetAll()
    if err != nil {
        c.JSON(500, gin.H{
            "message": err.Error(),
        })
        return
    }

    c.JSON(200, users)
}

Handler sebaiknya tidak berisi logika bisnis yang kompleks. Fokusnya hanya pada proses HTTP request dan response.

Service Layer

Service merupakan tempat logika bisnis aplikasi dijalankan.

Contoh:

type UserService struct {
    repo repository.UserRepository
}

func (s *UserService) GetAll() ([]model.User, error) {
    return s.repo.FindAll()
}

Jika terdapat validasi, perhitungan, atau aturan bisnis tertentu, semuanya sebaiknya ditempatkan pada layer ini.

Repository Layer

Repository bertugas berinteraksi langsung dengan database.

Contoh:

type UserRepository struct {
    db *sql.DB
}

func (r *UserRepository) FindAll() ([]model.User, error) {
    rows, err := r.db.Query(
        "SELECT id, name, email FROM users",
    )

    if err != nil {
        return nil, err
    }

    defer rows.Close()

    var users []model.User

    for rows.Next() {
        var user model.User

        err := rows.Scan(
            &user.ID,
            &user.Name,
            &user.Email,
        )

        if err != nil {
            return nil, err
        }

        users = append(users, user)
    }

    return users, nil
}

Dengan pola ini, perpindahan database dari MySQL ke PostgreSQL misalnya dapat dilakukan dengan perubahan yang lebih terisolasi.

Dependency Injection pada Layered Architecture

Agar setiap layer tidak membuat dependensinya sendiri, biasanya digunakan teknik Dependency Injection.

Contoh pada main.go:

db := database.Connect()

userRepo := repository.NewUserRepository(db)
userService := service.NewUserService(userRepo)
userHandler := handler.NewUserHandler(userService)

Dengan pendekatan ini, setiap komponen menerima dependensi dari luar sehingga lebih mudah diuji menggunakan mock saat unit testing.

Keuntungan Menggunakan Layered Architecture

Beberapa keuntungan yang diperoleh antara lain:

  • Struktur kode lebih terorganisir.
  • Tanggung jawab setiap komponen lebih jelas.
  • Lebih mudah melakukan unit testing.
  • Mempermudah pengembangan fitur baru.
  • Cocok untuk pengembangan tim karena alur kerja lebih terstruktur.
  • Mengurangi ketergantungan langsung antar komponen.
  • Memudahkan penerapan prinsip SOLID.

Kekurangan Layered Architecture

Meskipun populer, Layered Architecture juga memiliki beberapa kekurangan:

  • Membutuhkan lebih banyak file dan folder.
  • Untuk proyek kecil terasa terlalu kompleks.
  • Data sering harus melewati beberapa layer sekaligus.
  • Membutuhkan disiplin tim agar setiap layer tetap sesuai tanggung jawabnya.

Karena itu, penting menyesuaikan arsitektur dengan kebutuhan proyek.

Perbedaan Layered Architecture dan Clean Architecture

Banyak developer pemula menganggap keduanya sama, padahal terdapat perbedaan.

Layered ArchitectureClean Architecture
Struktur lebih sederhanaStruktur lebih kompleks
Cocok untuk proyek kecil hingga menengahCocok untuk proyek besar
Dependency biasanya mengarah ke bawahDependency mengarah ke domain
Implementasi lebih cepatLebih fleksibel dan scalable

Layered Architecture sering menjadi langkah awal yang baik sebelum mempelajari Clean Architecture yang lebih kompleks.

Kapan Sebaiknya Digunakan?

Layered Architecture sangat cocok digunakan pada:

  • REST API menggunakan Gin.
  • REST API menggunakan Fiber.
  • Backend aplikasi web.
  • Sistem internal perusahaan.
  • Dashboard administrasi.
  • Aplikasi skala menengah hingga besar.

Untuk aplikasi yang hanya memiliki beberapa endpoint sederhana, penggunaan banyak layer terkadang tidak memberikan manfaat yang signifikan.

Kesimpulan

Layered Architecture merupakan salah satu pola arsitektur yang paling umum digunakan dalam pengembangan backend Golang. Dengan memisahkan tanggung jawab ke dalam layer seperti Handler, Service, dan Repository, kode menjadi lebih mudah dirawat, diuji, dan dikembangkan dalam jangka panjang.

Pola ini membantu developer menjaga struktur proyek tetap rapi serta mempermudah kolaborasi dalam tim. Meskipun bukan solusi untuk semua kasus, Layered Architecture tetap menjadi fondasi yang kuat untuk membangun aplikasi Golang yang terstruktur dan mudah dipelihara.