Episode ini memandu langkah demi langkah membuat project Gin pertama: inisialisasi modul, install dependency, memahami gin.New() vs gin.Default(), mode debug dan release, membuat rute pertama, serta menjalankan server.

Sekarang saatnya menulis kode sungguhan. Episode 3 adalah titik di mana kalian membangun project Gin pertama yang benar-benar berjalan: dari direktori kosong, inisialisasi modul Go, pemasangan Gin, hingga server yang merespons endpoint pertama. Ini adalah fondasi operasional — semua episode berikutnya membangun di atas struktur ini, jadi pahami setiap langkahnya, bukan sekadar menyalin.
Mulai dengan membuat direktori dan modul Go:
mkdir hello-gin
cd hello-gin
go mod init hello-ginPerintah go mod init hello-gin menciptakan file go.mod yang mencatat nama modul dan versi Go. Selanjutnya install Gin:
go get github.com/gin-gonic/gin@v1.12.0
go mod tidygo mod tidy merapikan dependency: menghapus yang tidak terpakai dan memastikan go.sum lengkap. Sekarang struktur project minimal: go.mod, go.sum, dan file Go yang akan kita buat.
Ada dua cara membuat Engine, dan perbedaannya penting:
gin.New(): engine kosong tanpa middleware sama sekali.gin.Default(): engine dengan gin.Logger() dan gin.Recovery() sudah terpasang.r1 := gin.New()
r2 := gin.Default()
// r1 tidak punya middleware apapun
// r2 punya Logger + RecoveryUntuk belajar, gin.Default() adalah pilihan paling nyaman karena langsung mendapat log request dan proteksi dari panic. Di production, kalian bisa memakai gin.New() lalu menambahkan middleware yang lebih terkontrol — dibahas di episode 6.
Gin memakai mode debug secara default, ditandai log seperti [GIN-debug] GET /hello --> main.main.func1. Untuk mode release, set variabel lingkungan atau panggil gin.SetMode:
GIN_MODE=release go run main.gogin.SetMode(gin.ReleaseMode)
r := gin.Default()Mode release mematikan log rute dan beberapa pengecekan debug, sehingga lebih cepat dan ringkas di production.
Gin menyediakan method GET, POST, PUT, PATCH, DELETE langsung di Engine. Mari tulis file main.go lengkap:
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/hello", func(c *gin.Context) {
c.String(http.StatusOK, "hello world")
})
r.GET("/ping", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "pong"})
})
r.Run(":8080")
}c.String(http.StatusOK, "hello world") mengirim teks polos, sedangkan c.JSON mengirim objek JSON. gin.H adalah alias untuk map[string]any yang praktis untuk response sederhana.
go run main.gocurl http://localhost:8080/hello
curl http://localhost:8080/pingOutputnya hello world dan {"message":"pong"}. Fungsi r.Run(":8080") memanggil http.ListenAndServe(":8080", r) — Engine Gin memenuhi interface http.Handler, itulah mengapa Gin bisa disisipkan ke dalam net/http standar.
Endpoint GET sudah jalan. Sekarang tambahkan endpoint POST yang menerima JSON, lalu daftarkan handler-nya dengan r.POST("/todo", createTodo):
type Todo struct {
Title string `json:"title"`
}
func createTodo(c *gin.Context) {
var todo Todo
if err := c.ShouldBindJSON(&todo); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusCreated, gin.H{"title": todo.Title})
}c.ShouldBindJSON(&todo) memetakan body JSON ke struct Todo sesuai tag json:"title". Jika format salah, kita kembalikan status 400.
curl -X POST http://localhost:8080/todo \
-H "Content-Type: application/json" \
-d '{"title":"belajar gin"}'Perintah curl di atas mengirim header Content-Type: application/json dan body JSON. Ini pola standar REST API yang akan kalian pakai terus-menerus.
Untuk menutup episode, gabungkan method HTTP dalam satu aplikasi kecil. Kita simulasikan penyimpanan dengan slice di memori (database sungguhan di episode 9):
var todos = []gin.H{}
func main() {
r := gin.Default()
r.GET("/todos", func(c *gin.Context) {
c.JSON(http.StatusOK, todos)
})
r.POST("/todos", func(c *gin.Context) {
var body gin.H
if err := c.ShouldBindJSON(&body); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
todos = append(todos, body)
c.JSON(http.StatusCreated, body)
})
r.Run(":8080")
}Parameter path seperti :index akan dibahas lengkap di episode 4. Perhatikan pola umum: setiap handler menerima *gin.Context, membaca input, memproses, lalu menulis response.
Inti yang harus dibawa pulang:
go mod init lalu go get github.com/gin-gonic/gin@v1.12.0.gin.Default() = Engine + Logger + Recovery; gin.New() kosong.GIN_MODE=release untuk menonaktifkan log debug.c.String, c.JSON, dan c.ShouldBindJSON adalah API pertama yang wajib dikuasai.r.Run(":8080") menjalankan server karena Engine memenuhi http.Handler.Di episode 4 selanjutnya kita akan membedah routing & path parameter — pola /users/:id, wildcard /files/*filepath, query parameter, RouterGroup dengan prefix v1 dan v2, serta penanganan 404 dan 405.