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:

      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:

      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:

      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.

      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.

      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

Last updated