# RESTFul API dengan Gin dan Gorm

Pada sesi ini kita akan membuat service API menggunakan [Gin](https://gin-gonic.com/) sebagai HTTP Web Framework dan [Gorm](https://gorm.io/index.html) sebagai ORM library.

### Instalasi Gin dan Gorm

Gin dan Gorm adalah external package pada Go sehingga kita perlu melakukan instalasi:

```
go get -u github.com/gin-gonic/gin
```

dan

```
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
```

Untuk driver database disini kita akan menggunakan `mysql` .

### Setup Database

Kita akan melakukan setup dan koneksi ke database melalui Gorm. Silahkan membuat folder `config` pada root direktori program Go yang sudah dibuat. Lalu di dalam folder `config` buatlah sebiah file Go bernama `database.go` yang sekaligus menjadi bagian dari package `config`.

```go
package config
```

Kita akan mendeklarasikan variabel `DB` yang merupakan pointer dari `gorm.DB` .

```go
var DB *gorm.DB
```

Lalu kita akan membuat sebuah fungsi bernama `ConnectDatabase` untuk membuat setup koneksi ke database driver yang kita gunakan. Lengkapnya kamu bisa cek pada dokumentasi Gorm.

```go
  dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
  db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

```

Kita diminta memasukkan informasi database driver `mysql` yang kita gunakan yaitu `user`, `password` , dan nama database `dbname` .

```go
func ConnectDatabase() {
	dsn := "root:root@tcp(127.0.0.1:3306)/ptpgo?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

	if err != nil {
		log.Fatal(err.Error())
	}
	fmt.Println("Connected to Database")

	DB = db
}
```

Terakhir kita isi variabel `DB` yang digunakan untuk melakukan koneksi ke database. Untuk kode lengkapnya bisa dilihat di bawah ini:

```go
package config

import (
	"fmt"
	"log"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

var DB *gorm.DB

func ConnectDatabase() {
	dsn := "root:root@tcp(127.0.0.1:3306)/ptpgo?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

	if err != nil {
		log.Fatal(err.Error())
	}
	fmt.Println("Connected to Database")

	DB = db
}
```

### Koneksi ke Database

Kita telah membuat konfigurasi database, maka sekarang saatnya menghubungkan aplikasi Go kita dengan database. Buatlah file `main.go` seperti biasa pada root direktori. Lalu kita panggil package `gowebsiervice/config` yang telah kita buat sebelumnya:

```go
package main

import (
	"gowebservice/config"
)

func main() {
	config.ConnectDatabase()
}
```

Jika berhasil maka status koneksi akan menampilkan teks `Connected to Database` :

![Berhasil connect ke database](https://2969676661-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MQaVepPFjuLoNjbs6f8%2F-MTd1ll27DnD0ooa4lF8%2F-MTdxXpv-nyp1IYJfbpp%2FScreen%20Shot%202021-02-16%20at%2015.23.07.png?alt=media\&token=b5cc8b05-9791-4921-b550-10529ebf9e69)

### Membuat entity pada Database

Kita harus tahu aplikasi membutuhkan endpoint apa saja dari UI yang sudah disediakan. Namun pada kasus ini anggap saja kita membutuhkan endpoint data Students.

Kita akan membuat database bernama `ptpgo` dan table bernama `students` . Pada table kita akan mendaftarkan column `id` , `fullname` , `age` , dan `batch` .

Untuk menjalankan database SQL dengan driver [MySQL](https://dev.mysql.com/downloads/mysql/), pastikan kamu telah menginstal MySQL pada local komputer. Setelah itu kita bisa mengakses MySQL melalui command line ataupu GUI seperti [Dbeaver](https://dbeaver.io/) dan [Sequel Pro](https://www.sequelpro.com/).

Pada contoh ini kita akan menggunakan command line untuk memanipulasi data query SQL.

Untuk mengakses `MySQL` , ketik perintah berikut ini:

```
mysql -u root -p
```

Selanjutnya masukkan query berikut ini untuk membuat sebuah database bernama `goschool` :

```
CREATE DATABASE goschool;
```

Kita juga harus memilih database yang ingin digunakan:

```
USE goschool;
```

Selanjutnya kita akan membuat table dan column serta memasukkan beberapa data:

```
CREATE TABLE IF NOT EXISTS students (
  id int(5) NOT NULL AUTO_INCREMENT,
  fullname varchar(255) NOT NULL,
  age int(11) NOT NULL,
  batch varchar(100) NOT NULL,
  PRIMARY KEY (id)
);

INSERT INTO students (id, fullname, age, batch) VALUES
(1, 'Wisma Eka', 24, 'adorable'),
(2, 'Yudis', 22, 'brilliant'),
(3, 'Sukisno', 35, 'creative'),
(4, 'Guntur', 30, 'dilligent');
```

### Membuat Model

Kita akan membuat folder `models` yang berisi tiap entity yang ada pada aplikasi Go sebagai representasi dari table yang ada. Pada kasus ini kita akan membuat file Go `student.go` di dalam folder `models` sehingga kita jadikan file tersebut sebagai package `models` .

Pada file `student.go` kita akan membuat sebuah `struct` dari `Student` sebagai representasi table yang ada pada database.

```go
package models

type Student struct {
	Id        int       `json: "id"`
	Fullname  string    `json: "fullname"`
	Age       int       `json: "age"`
	Batch     string    `json: "batch"`
}
```

### Membuat Controller

Kita membutuhkan Controller sebagai perantara antara client dan juga model. Controller nantinya akan berisi handler dari setiap endpoint.

Buatlah sebuah folder bernama `controllers` yang didalamnya buatl juga sebuah file bernama `student.go` . Kita akan membuat handler bernama `GetStudents` untuk endpoint `/students` yang nanti akan kita daftarkan. Handler ini berfungsi untuk menampilkan seluruh data pada table `students` :

```go
package controllers

import (
	"gowebservice/config"
	"gowebservice/models"
	"net/http"
	
	"github.com/gin-gonic/gin"
)

func GetStudents(c *gin.Context) {
	var students []models.Student

	if err := config.DB.Find(&students).Error; err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Record not found!"})
		return
	}
	c.JSON(http.StatusOK, students)
}
```

### Setup Gin

Selanjutnya kita akan menggunakan Gin kembali pada file `main.go` untuk mendaftarkan endpoint yang akan kita gunakan. Kita akan membuat inisialisasi penggunaan Gin dengan variabel `r` :

```go
r := gin.Default()
```

Lalu akan mendaftarkan Endpoint yang kita butuhkan yaitu method `GET` dimana handler telah kita buat sebelumnya pada Controller:

```go
r.GET("/students", controllers.GetStudents)
```

Untuk menjalankan Gin kita perlu menambahkan statement:

```go
r.Run()
```

Sehingga kode lengkapnya menjadi seperti berikut ini:

```go
package main

import (
	"gowebservice/config"
	"gowebservice/controllers"

	"github.com/gin-gonic/gin"
)

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

	config.ConnectDatabase()

	r.GET("/students", controllers.GetStudents)

	r.Run()
}
```

### Menjalankan aplikasi dan testing endpoint

Kita akan menjalankan aplikasi seperti biasa yaitu `go run main.go` :

![Server berjalan melalui Gin](https://2969676661-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MQaVepPFjuLoNjbs6f8%2F-MTd1ll27DnD0ooa4lF8%2F-MTe7AM7_pvZGmpVS2ca%2FScreen%20Shot%202021-02-16%20at%2016.16.37.png?alt=media\&token=9cf553c4-adc9-4d5e-becb-be3b004355af)

Kita akan melakukan testing endpoint menggunakan [Postman](https://www.postman.com/) untuk memanggil endpoint yang telah kita daftarkan `/students` yang memiliki method `GET` :

![Endpoint /students berhasil dijalankan](https://2969676661-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MQaVepPFjuLoNjbs6f8%2F-MTd1ll27DnD0ooa4lF8%2F-MTe8xftLQcQb99ltm1f%2FScreen%20Shot%202021-02-16%20at%2016.23.02.png?alt=media\&token=30a510be-584d-47fa-a816-1cc117e15c11)
