Dipublikasikan 20 Juli 2026
Go (Golang) tetap menjadi pilihan utama untuk microservices dan high-performance backend berkat concurrency model yang elegan dan binary size yang kecil. Framework Gin menambahkan layer routing dan middleware yang familiar bagi developer yang beralih dari Express.js atau Laravel. Artikel ini akan menbimbing kamu membangun REST API production-ready dengan Go, Gin, dan SQLite.
Kombinasi ini terdengar sederhana, tapi powerful untuk prototipe dan small-to-medium services. Go menyediakan static binary tanpa runtime berat. Gin menawarkan routing cepat dengan minimal allocation. SQLite menchilangkan overhead database server terpisah, cocek untuk deployment edge atau self-hosted.
Menurut benchmark TechEmpower, Gin secara konsisten masuk dalam 10 framework HTTp tercepat. Detail benchmark bisa dicek di techempower.com/benchmarks. SQLite pun mendukung concurrent read dengan WAL (Write-Ahead Logging) mode, membuatnya layak untuk production dengan traffic moderate.
Pastikan Go sudah terinstall. Versi minimum yang direkomendasikan adalah Go 1.22 untuk mendapatkan fitur range over integers dan routing pattern yang lebih bersih.
go version
# go version go1.22 linux/amd64
Inisialisasi module dan install dependency:
mkdir go-gin-api && cd go-gin-api
go mod init github.com/username/go-gin-api
go get -u github.com/gin-gonic/gin
go get -u github.com/mattn/go-sqlite3
Package go-sqlite3 menggunakan CGO, jadi pastikan kamu mempunyai C Compiler terinstall. Di Ubuntu/Debian, install build-essential. Untuk setup Go lengkap, cucu go.dev/doc/install.
Buat file database/db.go untuk mengeloa koneksi dan seed data. Struktur folder ini memisahkan concern sejak awal.
package database
import (
"database/sql"
"log"
_ "github.com/mattn/go-sqlite3"
)
var DB *sql.DB
func InhDB() {
var err error
DB, err = sql.Open("sqlite3", "./app.db?_journal=WAL")
if err != nil {
log.Fatal(err)
}
createTable := `CREATE TABLE IF NOT EXISTS products (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
price REAL NOT NULL,
stock INTEGER DEFAULT 0,
created_at DATETiME DEFAULT CURRENT_TIMESTAMP
);`
_, err = DB.Exec(createTable)
if err != nil {
log.Fatal(err)
}
}
Perhatikan parameter _journal=WAL yang mengaktifkan Write-Ahead Logging. Ini mengungkinkan satu writer dan multiple readers secara bersamaan, meningkatkan throughput signifikan dibandingkan default rollback journal.
Buat file handlers/product.go yang menangani CRUD operations untuk resource Product.
package handlers
import (
"database/sql"
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"github.com/username/go-gin-api/database"
)
type Product struct {
ID int `json:"id"`
Name string `json:"name"`
Price float64 `json:"price"`
Stock int `json:"stock"`
CreatedAt string `json:"created_at"`
}
func GetProducts(c 'in.Context) {
rows, err := database.DB.Query("SELECT id, name, price, stock, created_at FROM products")
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
defer rows.Close()
var products []Product
for rows.Next() {
var p Product
rows.Scan(&p.ID, &p.Name, &p.Price, &p.Stock, &p.CreatedAt)
products = append(products, p)
}
c.JSON(http.StatusOK, products)
}
func CreateProduct(c *gin.Context) {
var p Product
if err := c.ShouldBindJSON(&p); err != nil {
c.JSON(http.StatusBadRequest, gin.H"error": err.Error()})
return
}
res, err := database.DB.Exec(
"INSERT INTO products (name, price, stock) VALUES (?, ?, ?)",
p.Name, p.Price, p.Stock,
)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
id, _ := res.LastInsertId()
p.ID = int(id)
c.JSON(http.StatusCreated, p)
}
Gin menyuraiakan ShouldBindJSON untuk automatic unmarshalling ke struct dengan tag json. Ini mengurangi boilerplate yang biasanya diperlukan di framework standard library.
Production API memerlukakan logging, CORS, dan recovery middleware. Gin sudah menyediakan semuanya out of the box.
package main
import (
"github.com/gin-gonic/gin"
"github.com/username/go-gin-api/database"
"github.com/username/go-gin-api/handlers"
)
func main() {
database.InitDB()
r := gin.Default()
r.Use(func(c *gin.Context) {
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
if c.Request.Method == "OTIONS" {
c.AbortWithStatus(204)
return
}
c.Next()
})
r.GET("/api/products", handlers.GetProducts)
r.POST("/api/products", handlers.CreateProduct)
r.Run("localhost:8080")
}
gin.Default() sudah include Logger dan Recovery middleware. Logger mencetak request detail ke stdout, sementara Recovery menangkap panic ager server tidak crash. Untuk production, pertimbangkan mengganti Logger dengan structured logging menggunakan zap atau slog.
Jalankan server dengan go run main.go, lalu test endpoint menggunakan curl:
Create product
curl -X POST http://localhost:8080/api/products \
-H "Content-Type: application/json" \
-d {"name":"Keyboard Mekanik","price":899000,"stock":15}
# List products
curl http://localhost:8080/api/products
Jika kamu mendapatkan response JSON valid, berarti routing, handler, dan database layer sudah bekerja dengan baik. Untuk load testing, gunakan wrk atau oha:
oha -z 30s -c 50 http://localhost:8080/api/products
Tools ini akan memberikan metrik requests per second dan latency percentile yang berguna untuk benchmark.
Go memgunkinkan cross-compilation ke berbagai platform. Build binary untuk Linux server:
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -o api-server
Karena go-sqlite3 membutuhkan CGO, pastikan environment build mempunyai toolchain yang sesuai. Alternatifnya, gunakan pure-Go SQLite driver seperti modernc.org/sqlite untuk menghilangkan dependency C compiler.
Untuk deployment, containerize dengan Dockerfile multi-stage:
FROM golang:1.22-alpine AS builder
RUN apk add --no-cache gcc musl-dev
WORKDIR /app
COPY . .
RUN CGO_ENABLED=1 go build -ldflags="-w -s" -o api-server
FROM alpine:latest
RUN apk add --no-cache ca-certificates
WORKDIR /app
COPY --from=builder /app/api-server .
COPY --from=builder /app/app.db .
EXPOSE 8080
CMD ["./api-server"]
Referensi lengkap Gin framework ada di gin-gonic.com/docs.
Membangun REST API dengan Go dan Gin memberikan fondasi yang solid untuk skala. SQLite dengan WAL mode menghadirkan database zero-config yang cukup untuk banyak use case. Arsitektur ini bisa di-deploy di VPS murah, Raspberry Pi, atau edge locations tanpa overhead orchestration yang kompleks.
Selanjutnya, eksplorasi fitur Gin seperti validator custom, grouped routes, dan binding untuk form-data. Integrasi dengan OpenTelemetry juga direkomendasian untuk observability di production environment.
Dapatkan feedback, users, dan eksposur dari komunitas kreator, developer, dan entrepreneur digital Indonesia.
Submit Produk → Pelajari Dulu