Cara membuat Http Server di Golang part 3

Untuk mendapatkan akses database di server silahkan bisa dipelajari terlebih dahulu Aiven kemudian taruh data host,port,username,database, dan password.

  1. Pertama, konfigurasikan koneksi ke database dalam file db.go di dalam folder Config:

project-folder/src/Config/db.go:

package Config

import (
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/postgres"
)

var DB *gorm.DB

func InitDB() *gorm.DB {
	var err error
	DB, err = gorm.Open("postgres", "host=pg-20772f0a-laravel.aivencloud.com port=21980 user=avnadmin dbname=defaultdb password=AVNS_F21ay59vewp2Aprj_pT sslmode=require")
	if err != nil {
		panic("failed to connect database")
	}
	return DB
}
  1. Selanjutnya, buat model untuk produk di dalam folder Models:

project-folder/src/Models/products.go:

package Models

import (
	"github.com/jinzhu/gorm"
)

type Product struct {
	gorm.Model
	Name  string `gorm:"type:varchar(100);unique_index" json:"name"`
	Price int    `gorm:"type:integer" json:"price"`
	Stock int    `gorm:"type:integer" json:"stock"`
}
  1. Kemudian, buat file products.go di dalam folder Controllers untuk menangani operasi CRUD:

project-folder/src/Controllers/products.go:

package Controllers

import (
	"encoding/json"
	"net/http"
	"project-folder/src/Config"
	"project-folder/src/Models"
	"github.com/jinzhu/gorm"
)

func GetAllProducts(w http.ResponseWriter, r *http.Request) {
	var products []Models.Product
	Config.DB.Find(&products)
	respondWithJSON(w, http.StatusOK, products)
}

func CreateProduct(w http.ResponseWriter, r *http.Request) {
	var product Models.Product
	err := json.NewDecoder(r.Body).Decode(&product)
	if err != nil {
		respondWithError(w, http.StatusBadRequest, "Invalid request payload")
		return
	}

	if err := Config.DB.Create(&product).Error; err != nil {
		respondWithError(w, http.StatusInternalServerError, err.Error())
		return
	}

	respondWithJSON(w, http.StatusCreated, product)
}

func UpdateProduct(w http.ResponseWriter, r *http.Request) {
	params := r.URL.Query()
	id := params.Get("id")
	var product Models.Product

	if err := Config.DB.First(&product, id).Error; err != nil {
		if gorm.IsRecordNotFoundError(err) {
			respondWithError(w, http.StatusNotFound, "Product not found")
		} else {
			respondWithError(w, http.StatusInternalServerError, err.Error())
		}
		return
	}

	var updatedProduct Models.Product
	err := json.NewDecoder(r.Body).Decode(&updatedProduct)
	if err != nil {
		respondWithError(w, http.StatusBadRequest, "Invalid request payload")
		return
	}

	product.Name = updatedProduct.Name
	product.Price = updatedProduct.Price
	product.Stock = updatedProduct.Stock

	Config.DB.Save(&product)
	respondWithJSON(w, http.StatusOK, product)
}

func DeleteProduct(w http.ResponseWriter, r *http.Request) {
	params := r.URL.Query()
	id := params.Get("id")
	var product Models.Product

	if err := Config.DB.First(&product, id).Error; err != nil {
		if gorm.IsRecordNotFoundError(err) {
			respondWithError(w, http.StatusNotFound, "Product not found")
		} else {
			respondWithError(w, http.StatusInternalServerError, err.Error())
		}
		return
	}

	Config.DB.Delete(&product)
	respondWithJSON(w, http.StatusOK, map[string]string{"message": "Product deleted successfully"})
}

func respondWithError(w http.ResponseWriter, code int, message string) {
	respondWithJSON(w, code, map[string]string{"error": message})
}

func respondWithJSON(w http.ResponseWriter, code int, payload interface{}) {
	response, _ := json.Marshal(payload)
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(code)
	w.Write(response)
}

Dalam contoh ini, kami menggunakan fungsi respondWithJSON dan respondWithError untuk mengirim tanggapan dalam format JSON. Metode CreateProduct, UpdateProduct, dan DeleteProduct menerima permintaan JSON dan mengembalikan respons JSON. GetAllProducts mengambil semua produk dari database dan mengembalikan dalam format JSON.

Pastikan Anda mengganti "id" dalam parameter URL dengan sesuatu yang sesuai dengan struktur URL Anda jika diperlukan. Sesuaikan juga rute dan logika operasi CRUD sesuai kebutuhan proyek Anda

memanggil InitDB di dalam fungsi main:

package main

import (
    "net/http"
    "project-folder/src/Config"
    "project-folder/src/Controllers"
)

func main() {
    // Inisialisasi koneksi ke database
    db := Config.InitDB()
    defer db.Close() // Pastikan untuk menutup koneksi ke database setelah selesai

    // Menetapkan handler untuk rute
    http.HandleFunc("/product", Controllers.GetAllProducts)
    http.HandleFunc("/product/create", Controllers.CreateProduct)
    http.HandleFunc("/product/update", Controllers.UpdateProduct)
    http.HandleFunc("/product/delete", Controllers.DeleteProduct)

    // Menjalankan server HTTP
    http.ListenAndServe(":8080", nil)
}

Dalam contoh di atas, InitDB dipanggil di dalam fungsi main sebelum server HTTP dimulai. Ini memastikan bahwa koneksi ke database dibuka saat aplikasi dimulai dan ditutup saat aplikasi berhenti. Penggunaan defer memastikan bahwa fungsi db.Close() akan dipanggil setelah fungsi main selesai dieksekusi.

Namun, dalam situasi yang lebih kompleks atau dalam aplikasi yang lebih besar, manajemen koneksi ke database dapat diintegrasikan dengan pola desain manajemen dependensi atau dalam kaitannya dengan kerangka kerja (framework) tertentu yang Anda gunakan. Sebaiknya pastikan untuk menutup koneksi ke database setelah selesai menggunakannya untuk menghindari kebocoran koneksi.

Last updated