Coding

Bikin REST API dengan Go: Tutorial Praktis untuk Pemula dari 0!

4 min read
Admin Admin

Daftar Isi

Setelah kemarin kita belajar bikin REST API pake Node.js, sekarang kita akan coba bikin REST API yang sama tapi pake Golang. Kita akan pake Gin framework yang terkenal dengan performanya yang cepet dan syntax yang simpel.

Persiapan

  • Go sudah terinstall (minimal versi 1.16)
  • Code editor (VS Code recommended + Go extension)
  • Postman untuk testing API
  • Basic knowledge Golang

1. Setup Project

Pertama, kita bikin project Go baru dan install dependencies yang dibutuhkan:

# Bikin folder project
mkdir go-rest-api
cd go-rest-api

# Inisialisasi Go module
go mod init go-rest-api

# Install Gin framework
go get -u github.com/gin-gonic/gin

2. Struktur Project

go-rest-api/
├── main.go
├── models/
│   └── book.go
├── go.mod
└── go.sum

3. Bikin Model

Buat file models/book.go:

package models

type Book struct {
  ID     int    `json:"id"`
  Title  string `json:"title"`
  Author string `json:"author"`
}

// Simulasi database dengan slice
var Books = []Book{
  {ID: 1, Title: "Harry Potter", Author: "J.K. Rowling"},
  {ID: 2, Title: "Lord of the Rings", Author: "J.R.R. Tolkien"},
}

4. Implementasi Main Server

Buat file main.go:

package main

import (
  "net/http"
  "strconv"
  "github.com/gin-gonic/gin"
  "go-rest-api/models"
)

func main() {
  router := gin.Default()

  // Routes akan ditambahkan di sini
  
  router.Run(":8080")
}

5. Implementasi CRUD Endpoints

GET - Ambil Semua Buku

// Tambahkan di main.go
router.GET("/books", func(c *gin.Context) {
  c.JSON(http.StatusOK, models.Books)
})

GET - Ambil Buku by ID

router.GET("/books/:id", func(c *gin.Context) {
  id, err := strconv.Atoi(c.Param("id"))
  if err != nil {
      c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid ID"})
      return
  }

  for _, book := range models.Books {
      if book.ID == id {
          c.JSON(http.StatusOK, book)
          return
      }
  }

  c.JSON(http.StatusNotFound, gin.H{"error": "Book not found"})
})

POST - Tambah Buku Baru

router.POST("/books", func(c *gin.Context) {
  var newBook models.Book
  if err := c.BindJSON(&newBook); err != nil {
      c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
      return
  }

  // Set ID baru
  newBook.ID = len(models.Books) + 1
  models.Books = append(models.Books, newBook)

  c.JSON(http.StatusCreated, newBook)
})

PUT - Update Buku

router.PUT("/books/:id", func(c *gin.Context) {
  id, err := strconv.Atoi(c.Param("id"))
  if err != nil {
      c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid ID"})
      return
  }

  var updatedBook models.Book
  if err := c.BindJSON(&updatedBook); err != nil {
      c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
      return
  }

  for i, book := range models.Books {
      if book.ID == id {
          updatedBook.ID = id
          models.Books[i] = updatedBook
          c.JSON(http.StatusOK, updatedBook)
          return
      }
  }

  c.JSON(http.StatusNotFound, gin.H{"error": "Book not found"})
})

DELETE - Hapus Buku

router.DELETE("/books/:id", func(c *gin.Context) {
  id, err := strconv.Atoi(c.Param("id"))
  if err != nil {
      c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid ID"})
      return
  }

  for i, book := range models.Books {
      if book.ID == id {
          models.Books = append(models.Books[:i], models.Books[i+1:]...)
          c.Status(http.StatusNoContent)
          return
      }
  }

  c.JSON(http.StatusNotFound, gin.H{"error": "Book not found"})
})

6. Middleware dan Validasi

Tambahkan validasi untuk request:

// Tambahkan struct tag untuk validasi
type Book struct {
  ID     int    `json:"id"`
  Title  string `json:"title" binding:"required,min=1"`
  Author string `json:"author" binding:"required,min=1"`
}

// Middleware untuk logging
router.Use(gin.Logger())

// Middleware untuk recovery dari panic
router.Use(gin.Recovery())

7. Testing dengan Postman

GET All Books

Postman GET Books Go

POST New Book

POST http://localhost:8080/books

Body:

{
  "title": "The Hobbit",
  "author": "J.R.R. Tolkien"
}

Tips Performance

  • Gunakan Gin di mode release untuk production
  • Implementasi caching untuk data yang sering diakses
  • Gunakan connection pooling saat integrasi dengan database
  • Manfaatkan goroutines untuk operasi concurrent

8. Pengembangan Lebih Lanjut

Database Integration

Integrasi dengan GORM + PostgreSQL/MySQL

Tertarik baca Hasilkan Uang dengan HTML dan CSS! 5 Cara Mudah Menghasilkan Penghasilan Tambahan Sambil Belajar Coding di sini.

JWT Authentication

Implement jwt-go untuk secure endpoints

Tertarik baca Belajar React Native dari Nol! Cara Membuat Aplikasi Mobile yang Bisa Dipakai di Android & iOS di sini.

Unit Testing

Tambahkan test dengan package testing

API Documentation

Gunakan Swagger untuk dokumentasi API

Kenapa Pakai Gin?

  • Performance yang sangat bagus
  • Built-in middleware support
  • Routing yang powerful
  • Komunitas yang besar

Troubleshooting

package not found

Jalankan go mod tidy untuk download dependencies

address already in use

Ganti port di router.Run() atau matikan aplikasi yang menggunakan port tersebut

Challenge!

Coba tambahkan fitur-fitur berikut:

  • Implementasi search dengan query parameter
  • Tambahkan pagination
  • Implement rate limiting middleware
  • Tambahkan file upload untuk cover buku