by Abu Zubayr

Crud API di Golang Menggunakan Echo Framework dan GORM

Crud API di Golang Menggunakan Echo Framework dan GORM

Bismillah...

Walhamdulillah, pada postingan sebelumnya kita sudah membahas mengenai Rest API di Golang Menggunakan Echo Framework. Pada postingan tersebut kita telah membahas tentang dasar-dasar pembuatan rest api di golang menggunakan framework yang diklaim lebih cepat dari Gin. Nah, postingan ini merupakan lanjutan dari postingan tersebut, jika anda belum membacanya sangat disarankan untuk mengikuti tutorial sebelumnya dari awal postingan.

Baiklah, di postingan ini kita akan mencoba membuat fungsi CRUD (Create, Read Update and Delete) sederhana menggunakan salah satu library ORM yang dipakai di golang yakni GORM. Untuk mengakses dokumentasi secara lengkap anda bisa menuju ke laman website resminya di https://gorm.io. Untuk studi kasus, kita akan membuat sebuah fungsi crud untuk tabel users. Dimana tabel tersebut berisi Email, Nama, No Handphone, Alamat dan KTP.

Buatlah sebuah database (nama database bebas) kemudian buat sebuah tabel dengan nama users. Untuk mempermudah anda bisa langsung copas script pembuatan tabel di bawah ini :
CREATE TABLE users (
	email VARCHAR(100) NOT NULL,
	nama VARCHAR(50) NOT NULL,
	no_handphone VARCHAR(15) DEFAULT NULL,
	alamat TEXT DEFAULT NULL,
	ktp VARCHAR(255) DEFAULT NULL,
	PRIMARY KEY (email) USING BTREE
);


Setelah selesai membuat tabel, langsung buka project sebelumnya. Beberapa yang akan kita lakukan adalah sebagai berikut :
  1. Membuat Koneksi Database
  2. Sebelum membuat konesi database, tambahkan terlebih dahulu modul GORM didalam project anda. Caranya adalah dengan memasukkan perintah di terminal/command line dengan :
    go get gorm.io gorm.io/driver/mysql

    Setelah selesai, buat terlebih dahulu sebuah direktori misalnya dengan nama config. Kemudian didalam direktori tersebut buat sebuah file dengan nama database.go. Isi file tersebut dengan kode seperti dibawah ini :
    package config
    
    import (
        "gorm.io/driver/mysql"
        "gorm.io/gorm"
    )
    
    var DB *gorm.DB
    
    func ConnectDB() {
        host := "localhost"
        port := "3306"
        dbname := "blogspot"
        username := "root"
        password := ""
    
        dsn := username + ":" + password + "@tcp(" + host + ":" + port + ")/" + dbname + "?charset=utf8&parseTime=true&loc=Local"
        var err error
        DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{SkipDefaultTransaction: true})
        if err != nil {
            panic("Cannot connect database")
        }
        DB.AutoMigrate()
    }

    Pada file database.go diatas, kita membuat sebuah variabel global dengan var DB *gorm.io. Variabel inilah yang nantinya akan kita gunakan untuk melakukan query ke database. Namun perlu diketahui bahwa cara penggunaan seperti ini tidak dianjurkan jika project yang dibuat dengan skala besar. Untuk project dengan skala besar disarankan untuk menerapkan clean arcitecture dimana koneksi database tidak di expose secara global, melainkan dibuat di masing-masing repository yang menyimpan database handler.

  3. Membuat Fungsi CRUD
  4. Selanjutnya kita akan membuat fungsi crud menggunakan koneksi database yang sudah dibuat sebelumnya. Supaya lebih teratur, maka fungsi crud tersebut akan saya buat terpisah dari file server.go. Untuk itu buat terlebih dahulu sebuah direktori baru lagi dengan nama model, kemudian buat sebuah file didalamnya dengan nama users.go. Didalam file ini kita akan memindahkan struct Users yang sebelumnya berada di file server.go ke file users.go. Isi dari file users.go adalah seperti dibawah ini :
    package model
    
    import "restapi/config"
    
    type Users struct {
        Email       string `json:"email" form:"email" gorm:"primaryKey"`
        Nama        string `json:"nama" form:"nama"`
        NoHandphone string `json:"no_handphone" form:"no_handphone"`
        Alamat      string `json:"alamat" form:"alamat"`
        Ktp         string `json:"ktp" form:"ktp"`
    }
    
    func (user *Users) CreateUser() error {
        if err := config.DB.Create(user).Error; err != nil {
            return err
        }
        return nil
    }
    
    func (user *Users) UpdateUser(email string) error {
        if err := config.DB.Model(&Users{}).Where("email = ?", email).Updates(user).Error; err != nil {
            return err
        }
        return nil
    }
    
    func (user *Users) DeleteUser() error {
        if err := config.DB.Delete(user).Error; err != nil {
            return err
        }
        return nil
    }
    
    func GetOneByEmail(email string) (Users, error) {
        var user Users
        result := config.DB.Where("email = ?", email).First(&user)
        return user, result.Error
    }
    
    func GetAll(keywords string) ([]Users, error) {
        var users []Users
        result := config.DB.Where("email LIKE ? OR nama LIKE ?", "%"+keywords+"%", "%"+keywords+"%").Find(&users)
    
        return users, result.Error
    }

    Penjelasan :
    • CreateUser
    • Method ini adalah method yang kita gunakan untuk melakukan insert ke database. Pada method ini memiliki penerima berupa struct Users. Artinya method CreateUser melekat pada struct Users, dan bisa diakses langsung oleh object struct tersebut. Kemudian method ini juga memiliki nilai balik atau return value berupa interface error. Method yang digunakan untuk insert data ke database melalui gorm adalah method Create, seperti yang terlihat di baris kode config.DB.Create(user). config.DB sendiri merupakan variabel koneksi database yang sebelumnya sudah kita buat di file database.go.
    • UpdateUser
    • Method ini merupakan method yang kita gunakan untuk melakukan update data ke database. Sama seperti method CreateUser, method ini juga memiliki penerima berupa struct Users. Kemudian method ini memiliki parameter berupa primary key dari tabel users yakni email. Jadi nantinya kita akan melakukan update data users berdasarkan email yang dimiliki oleh user tersebut. Yang perlu diperhatikan adalah pada bagian config.DB.Model(&Users), ini menandakan bahwa kita akan melakukan sesuatu di model atau tabel users. Kemudian dilanjutkan dengan method Where(“email = ?”, email) dimana ini merupakan filter user yang memiliki email tersebut yang akan kita update data-nya, dan dilanjutkan dengan method Updates(user) dimana method inilah yang akan melakukan perintah eksekusi update ke database.
    • DeleteUser
    • Kemudian method terakhir yang akan kita buat adalah method UpdateUser. Dimana method ini yang digunakan untuk menghapus data yang ada pada tabel users. Letak eksekusi perintah delete terdapat pada bagian config.DB.Delete(user).
    • GetOneByEmail
    • Fungsi ini digunakan untuk mengambil data di tabel users berdasarkan email. Jadi seperti yang sudah terlihat di baris kode, bahwa fungsi ini menerima parameter berupa string email. Kemudian return dari fungsi ini adalah struct Users dan error. Jika anda belum familiar dengan fungsi yang seperti ini saya kira wajar, karena saya sendiri juga baru menemukan di golang bahwa sebuah method atau fungsi bisa memiliki return value lebih dari 1 object atau nilai. Method yang digunakan gorm untuk melakukan select sendiri adalah method First. Dimana method ini akan melakukan select dengan limit 1 baris.
    • GetAll
    • Kemudian fungsi terakhir adalah fungsi GetAll. Fungsi ini merupakan fungsi yang akan kita gunakan untuk menampilkan data secara keseluruhan atau lebih dari 1 baris. Pada method ini juga saya masukkan sebuah parameter keywords, dimana parameter tersebut digunakan untuk melakukan filter dari query yang kita jalankan. Untuk return sendiri, fungsi ini memiliki 2 buah return value yakni array dari struct Users dan error.

  5. Mengubah Router
  6. Setelah selesai membuat method dan fungsi diatas, selanjutnya adalah mengubah bagian router di file server.go yang telah kita buat sebelumnya dengan kode seperti dibawah ini :
    config.ConnectDB()
    route := echo.New()
    route.POST("user/create_user", func(c echo.Context) error {
    	user := new(model.Users)
    	c.Bind(user)
    	contentType := c.Request().Header.Get("Content-type")
    	if contentType == "application/json" {
    		fmt.Println("Request dari json")
    	} else if strings.Contains(contentType, "multipart/form-data") || contentType == "application/x-www-form-urlencoded" {
    		file, err := c.FormFile("ktp")
    		if err != nil {
    			fmt.Println("Ktp kosong")
    		} else {
    			src, err := file.Open()
    			if err != nil {
    				return err
    			}
    			defer src.Close()
    			dst, err := os.Create(file.Filename)
    			if err != nil {
    				return err
    			}
    			defer dst.Close()
    			if _, err = io.Copy(dst, src); err != nil {
    				return err
    			}
    
    			user.Ktp = file.Filename
    			fmt.Println("Ada file, akan disimpan")
    		}
    	}
    	response := new(Response)
    	if user.CreateUser() != nil { // method create user
    		response.ErrorCode = 10
    		response.Message = "Gagal create data user"
    	} else {
    		response.ErrorCode = 0
    		response.Message = "Sukses create data user"
    		response.Data = *user
    	}
    	return c.JSON(http.StatusOK, response)
    })
    
    route.PUT("user/update_user/:email", func(c echo.Context) error {
    	user := new(model.Users)
    	c.Bind(user)
    	response := new(Response)
    	if user.UpdateUser(c.Param("email")) != nil { // method update user
    		response.ErrorCode = 10
    		response.Message = "Gagal update data user"
    	} else {
    		response.ErrorCode = 0
    		response.Message = "Sukses update data user"
    		response.Data = *user
    	}
    	return c.JSON(http.StatusOK, response)
    })
    
    route.DELETE("user/delete_user/:email", func(c echo.Context) error {
    	user, _ := model.GetOneByEmail(c.Param("email")) // method get by email
    	response := new(Response)
    
    	if user.DeleteUser() != nil { // method update user
    		response.ErrorCode = 10
    		response.Message = "Gagal menghapus data user"
    	} else {
    		response.ErrorCode = 0
    		response.Message = "Sukses menghapus data user"
    	}
    	return c.JSON(http.StatusOK, response)
    })
    
    route.GET("user/search_user", func(c echo.Context) error {
    	response := new(Response)
    	users, err := model.GetAll(c.QueryParam("keywords")) // method get all
    	if err != nil {
    		response.ErrorCode = 10
    		response.Message = "Gagal melihat data user"
    	} else {
    		response.ErrorCode = 0
    		response.Message = "Sukses melihat data user"
    		response.Data = users
    	}
    	return c.JSON(http.StatusOK, response)
    })
    
    route.Start(":9000")

    Di baris kode diatas, saya membuat sebuah struct Response. Isinya adalah sebagai berikut :
    type Response struct {
        ErrorCode int         `json:"error_code" form:"error_code"`
        Message   string      `json:"message" form:"message"`
        Data      interface{} `json:"data"`
    }

    Pada kode diatas, yang perlu anda perhatikan adalah pada bagian yang saya beri tanda komentar //. Pada bagian tersebutlah merupakan method dan fungsi yang kita panggil dari file users.go.
    Setelah selesai seluruhnya, sekarang kita lakukan pengujian terhadap api yang sudah dibuat menggunakan postman.
    1. Endpoint (user/create_user) POST
    2. Pengujian Rest Api Golang dengan Request multipart/form-data
      Pengujian menggunakan Content-Type : multipart/form-data
      Pengujian Rest Api Golang dengan Request application/json
      Pengujian menggunakan Content-Type : application/json

    3. Endpoint (user/update_user/:email) PUT
    4. Pengujian Rest Api Golang method PUT

    5. Endpoint (user/delete_user) DELETE
    6. Pengujian Rest Api Golang method DELETE

    7. Endpoint (user/search_user) GET
    8. Pengujian Rest Api Golang method GET tanpa parameter
      Request tanpa query params
      Pengujian Rest Api Golang method GET dengan query parameter
      Request dengan query params

Demikian tutorial Crud API di Golang Menggunakan Echo Framework dan GORM. Jika ada pertanyaan silahkan ditanyakan dikolom komentar dibawah. Untuk project juga sudah saya post di github bisa di cek di https://github.com/sardiabuzubayr/restapi-gorm.
Semoga bermanfaat, wassalamualaikum warahmatullah wabarakatuh
loading...
Share:

0 Comments:

Post a Comment

DigitalOcean Referral Badge
www.domainesia.com
Powered by Blogger.