# Go Project

* Berikut adalah best practice Go Project yang sudah diperbarui dengan poin-poin tambahan dan elaborasi lebih dalam:

  ### **1. Logging & Observability**

  #### ✅ **Slog & Multiwriter**

  * Gunakan **slog** sebagai structured logger bawaan Go 1.21 ke atas.
  * Manfaatkan **multiwriter** untuk menulis log ke beberapa output sekaligus, misalnya file dan stdout:

    ```go
    logger := slog.New(slog.NewJSONHandler(io.MultiWriter(os.Stdout, logFile), nil))
    slog.SetDefault(logger)
    ```
  * Pastikan log mencatat **trace ID** dan **context** untuk debugging lebih mudah.

  #### ✅ **Log File Rotation**

  * Gunakan **lumberjack** untuk merotasi log dan menghindari file log membengkak:

    ```go
    logFile := &lumberjack.Logger{
        Filename:   "app.log",
        MaxSize:    10, // MB
        MaxBackups: 3,
        MaxAge:     30, // days
        Compress:   true,
    }
    ```

  ### **2. Routing & API Framework**

  #### ✅ **Go Chi**

  * Gunakan **chi** untuk router yang ringan dan fleksibel dibandingkan `net/http`.
  * Support **middleware**, grouping routes, dan parameterized routing:

    ```go
    r := chi.NewRouter()
    r.Use(middleware.Logger)
    r.Get("/users/{id}", getUserHandler)
    ```

  ### **3. Database & Query Handling**

  #### ✅ **Postgres**

  * Gunakan **pgx** daripada database/sql untuk Postgres karena lebih cepat dan efisien.
  * Pastikan connection pooling optimal dengan **pgxpool**.

  #### ✅ **Raw Query (Instead of ORM like GORM)**

  * Hindari ORM seperti GORM untuk query kompleks agar lebih optimal.
  * Gunakan **pgx.NamedArgs** atau query builder ringan seperti **squirrel** jika diperlukan.

    ```go
    db.Exec("INSERT INTO users (name, email) VALUES ($1, $2)", name, email)
    ```

  #### ✅ **Transaction Handling**

  * Gunakan **manual transaction handling** dengan `BEGIN`, `COMMIT`, `ROLLBACK`.
  * Terapkan **unit of work pattern** untuk menghindari transaksi yang tidak terkelola dengan baik.

    ```go
    tx, err := db.Begin()
    if err != nil { return err }
    defer tx.Rollback()

    _, err = tx.Exec("UPDATE users SET balance = balance - $1 WHERE id = $2", amount, userID)
    if err != nil { return err }

    return tx.Commit()
    ```

  ### **4. Configuration Management**

  #### ✅ **Environment-Based Config**

  * Gunakan **Viper** atau **envconfig** untuk mengelola konfigurasi dari environment variables.
  * Hindari hardcoded config di dalam kode.

  ### **5. Dependency Injection (DI)**

  #### ✅ **Wire atau Fx**

  * Gunakan **Google Wire** atau **Fx** untuk dependency injection agar kode lebih terstruktur.
  * Jika ingin lebih ringan, gunakan **manual DI dengan constructor functions**.

  ### **6. Error Handling yang Konsisten**

  #### ✅ **Sentinel Errors & Wrapping**

  * Gunakan **sentinel errors** untuk kode error yang bisa dikenali.
  * Gunakan **fmt.Errorf** atau **errors.Join** untuk wrapping error dengan konteks tambahan.

  ### **7. Context Management**

  #### ✅ **Timeout & Deadline**

  * Selalu gunakan **context.Context** untuk request dan database call.
  * Atur **timeout** pada setiap request untuk menghindari goroutine leaks.

  ### **8. Security & Best Practices**

  #### ✅ **Input Validation & Hashing**

  * Gunakan **bcrypt** untuk hashing password.
  * Validasi input dengan **go-playground/validator**.

  #### ✅ **Rate Limiting & Secrets Management**

  * Gunakan **golang.org/x/time/rate** atau Redis untuk membatasi request.
  * Simpan credential di **secrets manager** (bukan di kode).

  ### **9. Efficient Goroutine & Worker Pool Management**

  #### ✅ **Worker Pool & sync.Pool**

  * Gunakan **worker pool** untuk task concurrent.
  * Gunakan **sync.Pool** untuk mengelola objek yang sering dialokasikan ulang.

  ### **10. Graceful Shutdown**

  #### ✅ **Handling SIGINT/SIGTERM**

  * Pastikan aplikasi menangani **SIGINT/SIGTERM** untuk shutdown yang bersih.
  * Tutup semua koneksi database, cache, dan WebSocket saat aplikasi berhenti.

  ### **11. Modul & Package Organization**

  #### ✅ **Domain-Driven Design (DDD) & Separation of Concerns**

  * Pisahkan kode ke dalam layer seperti **repository, service, handler** agar lebih maintainable.

  ### **12. CI/CD & Deployment**

  #### ✅ **GitHub Actions / GitLab CI**

  * Gunakan **CI/CD pipeline** untuk otomatisasi testing dan deployment.
  * Pastikan ada **health check endpoint** untuk monitoring di production 🔥

Database Documentation = <https://dbdocs.io/?utm_source=dbdocs>

Migration DB = <https://github.com/golang-migrate/migrate>
