Clean architecture
Setelah kita memiliki API yang terhubung ke database, sekarang saatnya memikirkan struktur kode. Tanpa arsitektur yang jelas, kode akan sulit di-maintain, sulit di-test, dan sulit dikembangkan oleh tim.
Clean Architecture (diperkenalkan oleh Robert C. Martin) adalah pendekatan yang memisahkan kode ke dalam lapisan-lapisan (layer) berdasarkan tanggung jawabnya.
📂 Kode Lengkap Bab Ini: Seluruh kode yang dibahas di bab ini tersedia di GitHub:
🔗 github.com/jacky-htg/workshop/tree/main/05-clean-architecture
5.1 Tiga Layer Utama

PRESENTATION LAYER (HTTP Handler, Routing, Request/Response DTO) :
Menerima input dari user
Memformat output ke user
TIDAK boleh mengandung logika bisnis
DOMAIN LAYER (Service / UseCase) :
Logika bisnis aplikasi
Aturan bisnis & validasi
Tidak peduli dari mana data berasal
DATA LAYER (Repository, Model) :
Akses database / API eksternal
Mapping data dari storage ke struct
Hanya operasi CRUD sederhana
Prinsip utama: Ketergantungan hanya mengarah ke dalam (inward). Layer dalam (Domain) tidak boleh tahu tentang layer luar (Presentation/Data).
5.2 Struktur Direktori
Berikut struktur direktori yang akan kita bangun:
Catatan tentang folder internal dan pkg:
internal/– Kode yang hanya boleh digunakan oleh proyek ini. Go compiler akan melarang import dari luar.pkg/– Kode yang boleh diimport oleh proyek lain (library publik).
5.3 Memisahkan Entry Points (Server vs CLI)
Sebelumnya, kita mencampur logika server HTTP dan migration dalam satu main.go. Sekarang kita pisahkan:
cmd/server/main.go – Entry Point untuk API Server
Menjalankan HTTP server, graceful shutdown, dan injeksi dependency.
cmd/cli/main.go – Entry Point untuk Command Line
Menjalankan perintah administrasi seperti migration.
5.4 Dependency Injection dengan Interface
Dependency Injection (DI) memastikan setiap object hanya dibuat sekali (singleton) dan disuntikkan ke komponen yang membutuhkan. Kita sudah mempraktekkannya sebelumnya dengan NewUsers(db).
Sekarang kita tingkatkan dengan interface. Interface mendefinisikan kontrak behavior — apa yang bisa dilakukan, bukan bagaimana cara melakukannya.
Konvensi penamaan interface:
Jika berisi satu behavior → akhiri dengan
-er(contoh:Reader,Writer)Jika berisi banyak behavior →
PascalCase(contoh:UserRepository)
Mengapa interface penting untuk DI?
Memungkinkan kita mengganti implementasi (misal: dari PostgreSQL ke MongoDB) tanpa mengubah kode lain
Memudahkan unit testing dengan mock object
5.5 Implementasi Layer per Layer
Layer Data – Model (internal/model/user.go)
Model adalah representasi struktur data dari database. Tidak mengandung tag JSON karena ini murni untuk layer data.
Layer Data – Repository (internal/repository/user_repository.go)
Repository bertanggung jawab untuk operasi database. Hanya berisi query sederhana — tanpa logika bisnis.
Berikut isi dari file
pkg/database/postgre.go
Layer Domain – Service (internal/service/users.go)
Service berisi logika bisnis. Di contoh sederhana ini, service hanya meneruskan ke repository. Namun nanti di sinilah validasi, perhitungan, dan aturan bisnis lainnya berada.
Layer Presentation – DTO (internal/dto/user_response.go)
DTO (Data Transfer Object) adalah representasi data yang dikirim ke client. Tidak semua field dari model harus diekspos — misalnya, field Password tidak boleh dikirim ke response.
Perhatikan: Field Password tidak ada di UserResponse — ini sengaja agar password tidak bocor ke client.
Layer Presentation – Handler (internal/handler/user_handler.go)
Handler menerima HTTP request, memanggil service, lalu mengubah hasil menjadi JSON response.
Library Pendukung – Database (pkg/database/postgre.go)
Kode ini bisa dijadikan library karena tidak spesifik untuk proyek ini.
Entry Point Server (cmd/server/main.go)
Ini adalah tempat perakitan semua komponen (dependency injection). Urutan inisialisasi: database → repository → service → handler.
5.6 Menjalankan Aplikasi
Ringkasan Bab 5
Di bab ini kita telah belajar:
Model
internal/model
Struktur data dari database
Repository
internal/repository
Operasi database (CRUD)
Service
internal/service
Logika bisnis
DTO
internal/dto
Format response ke client
Handler
internal/handler
Menerima request, mengembalikan response
Library
pkg
Kode yang bisa digunakan ulang
Entry point
cmd
Server HTTP dan CLI tools
Manfaat Clean Architecture yang sudah kita rasakan:
✅ Pemisahan tanggung jawab yang jelas
✅ Model data tidak terikat dengan format JSON
✅ Password tidak bocor ke response (karena dipisah di DTO)
✅ Repository bisa diganti tanpa mengubah service/handler
✅ CLI dan server berbagi kode yang sama
Yang akan datang:
❌ Belum ada konfigurasi (database URL masih hardcoded)
❌ Belum ada error handling yang terstruktur
❌ Belum ada validasi input
Pada bab berikutnya, kita akan membahas Configuration — bagaimana mengelola konfigurasi aplikasi (database URL, port, timeout) tanpa hardcode.
Last updated
Was this helpful?