> For the complete documentation index, see [llms.txt](https://zakimaliki.gitbook.io/golang/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://zakimaliki.gitbook.io/golang/cara-membuat-http-server-di-golang-part-3.md).

# Cara membuat Http Server di Golang part 3

Untuk mendapatkan akses database di server silahkan bisa dipelajari terlebih dahulu [Aiven](https://zakimaliki.gitbook.io/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:**

```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
}
```

2. **Selanjutnya, buat model untuk produk di dalam folder `Models`:**

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

```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"`
}
```

3. **Kemudian, buat file `products.go` di dalam folder `Controllers` untuk menangani operasi CRUD:**

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

```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`:

```go
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.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://zakimaliki.gitbook.io/golang/cara-membuat-http-server-di-golang-part-3.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
