AdityaDees: Backend

Hot

https://publishers.chitika.com/

Contact us for advertising.
Showing posts with label Backend. Show all posts
Showing posts with label Backend. Show all posts

27 December 2021

Ask Dimanakah Sebaiknya Menyimpan Konfigurasi di Golang? AdityaDees

00:22 0
Dimanakah Sebaiknya Menyimpan Konfigurasi di Golang?
Bismillah

Setiap aplikasi yang kita buat tentu membutuhkan settingan konfigurasi. Konfigurasi tersebut pun bermacam-macam, bisa berupa konfigurasi database, email, url aplikasi dan lain-lain. Nah, lantas bagaimanakah sebaiknya settingan tersebut dilakukan? Apakah settingan tersebut langsung ditulis di dalam source code project anda? Tentu saja tidak jawabannya. Menulis langsung konfigurasi di dalam source code aplikasi anda akan membuat proses maintenance menjadi sangat sulit dilakukan. Bayangkan saja misalnya didalam source code anda terdapat konfigurasi yang berbeda-beda file-nya, satu ada di direktori ini dan yang lainnya tersebar di berbagai direktori lainnya. Dan ketika terjadi perubahan dengan konfigurasi itu, anda harus membongkar source code tersebut dan mencarinya satu persatu. Bayangkan pula model penulisan konfigurasi seperti ini anda buat bukan hanya satu project saja, tapi juga di project lainnya anda lakukan hal yang sama. Waah, pasti pusing tujuh keliling anda dibuatnya, hal seperti ini membutuhkan waktu yang lama dan melelahkan. Lalu apa solusinya? kita bahas lebih lanjut.

Umumnya konfigurasi sebuah aplikasi ditulis didalam file tersendiri, baik berupa file dengan eksistensi .env (environment), .properties, .json atau bentuk-bentuk lainnya. Yang jelas, file konfigurasi tersebut berada diluar source code aplikasi itu sendiri. Didalam postingan ini saya akan memberikan contoh bagaimana cara membuat file konfigurasi tersebut. Saya hanya mencontohkan cara membuat file konfigurasi tersebut menggunakan bahasa Go atau Golang. Untuk bahasa lainnya anda bisa mencari dari referensi lain, secara penerapan sama insyaAllah.

Ada beberapa library atau modul yang bisa anda gunakan di golang untuk menulis file konfigurasi diantaranya adalah modul godotenv atau juga bisa menggunakan vifer. Di tutorial ini saya mencontohkan file konfigurasi tersebut ditulis di file main.go, untuk project real, biasanya konfigurasi tersebut di buat di file khusus misalnya di config atau yang lainnya.
Baiklah langsung saja kita coba mempraktekkan bagaimana cara menggunakan modul tersebut satu persatu.

  1. GODOTENV
  2. Penggunaan library ini biasanya digunakan dengan eksistensi file .env. Untuk membuat konfigurasi menggunakan library ini, langkah-langkahnya adalah sebagai berikut :
    • Di project direktori anda, buka terminal/command line kemudian masukkan perintah :
    • go get github.com/joho/godotenv
    • Setelah selesai, buat sebuah file dengan eksistensi .env
    • Didalam file tersebut, tulis isi konfigurasi anda dengan format key-value, misalnya : APP-NAME=Belajar Konfigurasi Golang dimana APP-NAME adalah key, sedangkan Belajar Konfigurasi Golang merupakan value.
    • Selanjutnya buka file main.go jika sudah ada, atau jika belum buat file baru dengan nama main.go, kemudian masukkan source code seperti dibawah ini :
    • err := godotenv.Load(".env")
      if err != nil {
          panic("Cannot load .env file")
      }
      fmt.Println("Membuka konfigurasi menggunakan file .env")
      fmt.Println("==========================================")
      fmt.Println(os.Getenv("APP-NAME"))
      fmt.Println(os.Getenv("APP-GITHUB-PROJECT"))
      fmt.Println(os.Getenv("OWNER"))

      Penjelasan :
      • godotenv.Load(“.env”), artinya kita akan memuat atau membuka file .env tersebut, yang perlu diperhatikan adalah dimana anda menyimpan file .env tersebut, pastikan path dari file tersebut sudah benar karena jika path-nya salah maka akan terjadi error.
      • os.Getenv(“”), pada fungsi inilah kita menentukan key mana yang akan dipanggil.
  3. VIPER
  4. Viper sendiri lebih luas penggunaannya tidak berpatokan hanya satu jenis tipe file konfigurasi saja. Dengan viper anda bisa menulis konfigurasi dalam format JSON, TOML, YAML, HCL, INI, env, atau properties yang biasa di pakai di bahasa Java. Pada contoh ini kita akan mencoba menggunakan format JSON dan YAML. Adapun langkah-langkah untuk membuat konfigurasi menggunakan Viper adalah sebagai berikut :
    • Di project direktori anda, buka terminal/command line kemudian masukkan perintah :
    • go get github.com/spf13/viper
    • Kemudian, buat sebuah file dengan nama config.json
    • Tulis isi konfigurasi anda didalam file tersebut seperti menulis json pada umumnya, sebagai contoh seperti dibawah ini :
    • {
          "app_name":"Belajar Konfigurasi Golang",
          "app_github_project":"https://github.com/sardiabuzubayr",
          "owner":"AdityaDS",
          "port":3306
      }
    • Selanjutnya buka file main.go jika sudah ada, atau jika belum buat file baru dengan nama main.go, kemudian masukkan source code seperti dibawah ini :
    • viper.SetConfigName("config")
      viper.SetConfigType("json")
      viper.AddConfigPath(".")
      err = viper.ReadInConfig()
      if err != nil {
          panic("Cannot load configuration file")
      }
      fmt.Println("Membuka konfigurasi menggunakan file json (tanpa menentukan tipe data dari konfigurasi)")
      fmt.Println(viper.Get("app_name"))
      fmt.Println(viper.Get("app_github_project"))
      fmt.Println(viper.Get("owner"))
      fmt.Println(viper.Get("port"))

      fmt.Println("Membuka konfigurasi menggunakan file json (dengan menentukan tipe data dari konfigurasi)")
      fmt.Println(viper.GetString("app_name"))
      fmt.Println(viper.GetString("app_github_project"))
      fmt.Println(viper.GetString("owner"))
      fmt.Println(viper.GetInt("port"))

      Penjelasan :
      • viper.SetConfigName("config"), pada baris kode ini kita menentukan apa nama file konfigurasi yang akan dibaca oleh viper.
      • viper.SetConfigType("json"), bagian ini kita menentukan apa jenis file config yang kita gunakan.
      • viper.AddConfigPath("."), bagian ini menentukan dimana posisi file konfigurasi tersebut di tempatkan.
      • viper.ReadInConfig(), baris kode ini digunakan untuk memuat file konfigurasi tersebut, jika sudah benar nama, jenis, dan dimana file tersebut disimpan maka tidak akan terjadi error dibagian ini.
      • viper.Get(""), pada fungsi inilah kita tentukan key mana yang akan dipanggil. Fungsi ini bersifat global artinya seluruh data baik yang bertipe string atau angka bisa dipanggil dengan fungsi yang sama. Atau bisa juga dengan menggunakan fungsi yang lebih spesifik misalnya GetString untuk mengambil key yang datanya adalah karakter, atau GetInt untuk data yang bertipe integer, atau masih banyak lagi tipe yang disediakan oleh viper.

      Diatas adalah contoh tipe konfigurasi dengan file json. Untuk membuat dan membaca konfigurasi dengan file yaml, caranya sama, hanya saja format file konfigurasi ditulis mengikuti format yaml. Sebagai contoh adalah sebagai berikut :
      app_name: Belajar Konfigurasi Golang
      app_github_project: https://github.com/sardiabuzubayr
      owner: AdityaDS
      port: 3306

      Kemudian dibagian kode SetConfigType, masukkan “yaml” sehingga menjadi seperti viper.SetConfigType("yaml").
Source code keseluruhan terlihat seperti dibawah ini :
package main

import (
"fmt"
"os"

"github.com/joho/godotenv"
"github.com/spf13/viper"
)

func main() {
err := godotenv.Load(".env")
if err != nil {
panic("Cannot load .env file")
}
fmt.Println("Membuka konfigurasi menggunakan file .env")
fmt.Println("==========================================")
fmt.Println(os.Getenv("APP-NAME"))
fmt.Println(os.Getenv("APP-GITHUB-PROJECT"))
fmt.Println(os.Getenv("OWNER"))

viper.SetConfigName("config")
viper.SetConfigType("json")
viper.AddConfigPath(".")
err = viper.ReadInConfig()
if err != nil {
panic("Cannot load configuration file " + err.Error())
}
fmt.Println("Membuka konfigurasi menggunakan file json (tanpa menentukan tipe data dari konfigurasi)")
fmt.Println(viper.Get("app_name"))
fmt.Println(viper.Get("app_github_project"))
fmt.Println(viper.Get("owner"))
fmt.Println(viper.Get("port"))

fmt.Println("Membuka konfigurasi menggunakan file json (dengan menentukan tipe data dari konfigurasi)")
fmt.Println(viper.GetString("app_name"))
fmt.Println(viper.GetString("app_github_project"))
fmt.Println(viper.GetString("owner"))
fmt.Println(viper.GetInt("port"))

viper.SetConfigName("config")
viper.SetConfigType("yaml")
viper.AddConfigPath(".")
err = viper.ReadInConfig()
if err != nil {
panic("Cannot load configuration file " + err.Error())
}
fmt.Println("Membuka konfigurasi menggunakan file yaml (tanpa menentukan tipe data dari konfigurasi)")
fmt.Println(viper.Get("app_name"))
fmt.Println(viper.Get("app_github_project"))
fmt.Println(viper.Get("owner"))
fmt.Println(viper.Get("port"))

fmt.Println("Membuka konfigurasi menggunakan file yaml (dengan menentukan tipe data dari konfigurasi)")
fmt.Println(viper.GetString("app_name"))
fmt.Println(viper.GetString("app_github_project"))
fmt.Println(viper.GetString("owner"))
fmt.Println(viper.GetInt("port"))
}


Demikian tutorial singkat mengenai Dimanakah Sebaiknya Menyimpan Konfigurasi di GolangDimanakah Sebaiknya Menyimpan Konfigurasi di Golang.
Read More

25 December 2021

Ask Crud API di Golang Menggunakan Echo Framework dan GORM AdityaDees

11:20 0
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
Read More

20 December 2021

Ask Rest API di Golang Menggunakan Echo Framework AdityaDees

18:57 0
Rest API di Golang Menggunakan Echo Framework
Bismillah...
Perkembangan teknologi dewasa ini sangatlah cepat, dulu kita sering menggunakan Soap sebagai protokol untuk pertukaran data lintas platform, akan tetapi seiiring berjalannya waktu, protokol tersebut pelan-pelan mulai ditinggalkan karena kemunculan protokol baru untuk pertukaran data yakni Rest API yang menawarkan kecepatan yang lebih baik dari pendahulunya.

Pada postingan ini saya akan membuat sebuah contoh penggunaan rest api dengan menggunakan bahasa golang, khususnya dengan menggunakan framework echo. Mengapa saya menggunakan golang untuk membuat rest api ini? Jawabannya karena saya sedang mempelajari bahasa golang, hhhee. Saya tertarik mempelajari bahasa golang karena dari segi kecepatannya sangat luar biasa cepat jika dibandingkan dengan bahasa lain. Sebelumnya saya pernah membandingkan rest api golang dengan php (framework Lumen). Hasilnya sangat beda jauh dari segi kecepatan. Pada simple case, lumen memerlukan 100 - 200 ms untuk merespon sebuah permintaan dan mengembalikan dalam bentuk json. Akan tetapi golang hanya memerlukan waktu 3 - 10 ms untuk untuk merespon permintaan tersebut. Kemudian dengan menggunakan J-Meter untuk test permintaan secara concurent atau request secara bersamaan (1000 - 2000 request secara bersamaan), hasil yang didapat semakin jauh berbeda. Lumen memerlukan 6000 an ms atau 6 second keatas, akan tetapi golang masih dibawah 1 second. Luarrr biasa, hal inilah yang mendorong saya untuk mempelajari lebih lanjut mengenai golang dan tentu harapan kedepannya adalah menggunakan golang ini sebagai bahasa utama saya disisi backend.

Didalam bahasa golang sendiri, secara default sudah menyediakan sebuah package net/http. Didalam package tersebut sudah tersedia untuk  web server, routing, templating dan lainnya. Akan tetapi untuk lebih mempermudah saya menggunakan framework tambahan yaitu echo framework. Dokumentasi dari framework ini secara lengkap bisa diakses di https://echo.labstack.com. Echo sendiri mengklaim bahwa dirinya lebih baik dari Gin framework yang juga merupakan framework untuk develop website di go. Ini bisa dilihat dari github echo framework di https://github.com/labstack/echo.

Baiklah langsung saja, ditulisan ini saya akan memasukkan beberapa hal yang umum kita gunakan di rest api seperti POST, PUT, GET dan DELETE. Disini saya tidak memasukkan data yang dikirim kedalam database. Akan tetapi hanya sekedar mengirim dan membaca data secara statis saja. InsyaAllah pada kesempatan lain saya akan membuat rest api ini lengkap dengan database, yassarallahu li.

Disini saya berasumsi anda sudah menginstal golang, jika belum bisa menginstal langsung dari website resmi golang di https://go.dev . Baiklah jika sudah terinstall di laptop atau pc anda kita akan langsung mulai :
  1. Buat sebuah direktori/folder beri saja namanya restapi misalnya
  2. Kemudian buka terminal atau command line anda dan masukkan perintah go mod init restapi
  3. go mod init restapi
    Dari perintah di atas akan menghasilkan sebuah file go.mod. Didalam file ini seluruh modul yang akan kita gunakan akan di definisikan di file tersebut.
  4. Setelah itu tambahkan modul echo framework dengan perintah :
  5. go get github.com/labstack/echo/v4
    Perintah diatas kita gunakan untuk menambahkan sebuah modul baru yakni modul echo framework tadi.
  6. Selanjutnya buka editor kesayangan anda, disini saya menggunakan Visual Studio Code. Didalam project directory anda, buat sebuah file dengan nama server.go.
  7. Didalam file server.go kita akan membuat sebuah struct yang memuat entitas user seperti email, nama, no_handphone, alamat dan ktp. Berikut adalah isi dari struct tersebut :
  8. type Users struct {
        Email       string `json:"email" form:"email"`
        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"`
    }
    Pada struct diatas, kita sudah mendefinisikan entitas user. Yang perlu anda perhatikan adalah pada keyword json dan form. Keyword diatas berarti kita menentukan nama variabel yang digunakan untuk pertukaran data di rest api nantinya. Dimana keyword json ini akan terbaca pada saat data yang kita kirimkan dengan Content-Type application/json. Kemudian form akan terbaca jika Content-Type yang dikirim berupa multipart/form-data atau application/x-www-form-urlencoded.
  9. Kemudian di file yang sama, kita akan menginisialisasi fungsi dari framework echo yang akan kita gunakan sebagai web server sekaligus routing dari api yang kita buat. Tambahkan baris kode dibawah ini :
  10. func main() {
    route := echo.New()
    route.POST("user/create_user", func(c echo.Context) error {

    })
    route.PUT("user/update_user/:email", func(c echo.Context) error {

    })
    route.DELETE("user/delete_user/:email", func(c echo.Context) error {

    })
    route.GET("user/search_user", func(c echo.Context) error {

    })
    route.Start(":9000")
    }
    Pada source code diatas di function main, kita deklarasikan sebuah variabel route dengan inisialisasi function echo.New(). Function tersebut merupakan instance dari framework echo. Kemudian dilanjutkan kita definisikan method-method seperti POST, PUT, DELETE dan GET yang selanjutnya akan kita tulis kode didalamnya satu persatu.
  11. Selanjutnya dibagian method POST kita akan definisikan bahwa method tersebut akan menerima request dalam bentuk Content-Type application/json ataupun multipart/form-data. Sehingga baris kode pada method tersebut menjadi seperti berikut ini :
  12. 	user := new(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 := struct {
                Message string
                Data    Users
            }{
                Message: "Sukses melakukan penambahan data",
                Data:    *user,
            }
            return c.JSON(http.StatusOK, response)
    Penjelasan :
    • user := new(Users). Keyword new merupakan instance dari sebuah struct dalam hal ini Users. Variabel user menampung data pointer bertipe struct User.
      c.Bind(user) . Merupakan fungsi yang disediakan oleh framework echo untuk melakukan binding field yang dikirim oleh client kedalam sebuah interface.
      Cara diatas juga bisa diganti dengan kode seperti ini :
      var user Users
      c.Bind(&user)
    • contentType := c.Request().Header.Get("Content-type") digunakan untuk mengetahui jenis Content-Type apa yang dikirim oleh client.
    • Pada bagian selanjutnya hanya berupa pengecekan apa jenis content-type tadi. Kemudian khusus bagian :
      else if strings.Contains(contentType, "multipart/form-data") || contentType == "application/x-www-form-urlencoded" { …. } didalam blok kode tersebut saya mengecek apakah ada file yang dikirim, karena untuk Content-Type json tidak bisa mengirim data dalam bentuk file. Jika ada file yang dikirim, maka akan saya simpan file tersebut. Selanjutnya nama file yang dikirim tadi akan saya masukkan ke variabel ktp.
    • return c.JSON(http.StatusOK, user) merupakan response yang akan dikembalikan ke client yakni dalam bentuk json dari struct user tadi.
      http.StatusOK merupakan response code 200 yang dikembalikan ke client.
  13. Beralih ke method selanjutnya yakni method PUT. Pada method PUT ini umumnya digunakan untuk pengupdatan/perubahan data. Pada method ini masukkan kode berikut :
  14. 	user := new(Users)
            c.Bind(user)
            user.Email = c.Param("email")
            // do something here ....
            response := struct {
                Message string
                Data    Users
            }{
                Message: "Sukses mengupdate data",
                Data:    *user,
            }
            return c.JSON(http.StatusOK, response)
    Penjelasan :
    • c.Param(“email”) digunakan untuk mengambil parameter dari url. Dalam hal ini parameter yang ada di method PUT tersebut adalah email.
  15. Kemudian dibagian method DELETE. Method ini digunakan untuk melakukan penghapusan data. Sama seperti method PUT, biasanya method DELETE juga menyertakan sebuah ID untuk identifikasi data mana yang akan dihapus. Isi dari method DELETE seperti berikut ini :
  16. 	user := new(Users)
            user.Email = c.Param("email")
            // do something here ....
            response := struct {
                Message string
                ID      string
            }{
                Message: "Sukses menghapus data",
                ID:      user.Email,
            }
            return c.JSON(http.StatusOK, response)
  17. Terakhir adalah method GET. Method ini biasanya digunakan untuk melakukan request data ke server. Dan biasanya method ini juga mengirimkan sebuah query parameter. Berikut adalah contohnya :
  18. 	user := new(Users)
            user.Email = c.QueryParam("keywords")
            user.Nama = "AdityaDS"
            user.ALamat = "Jalan Jalan"
            user.Ktp = "file.jpg"
            // do something here ....
            response := struct {
                Message string
                Data    Users
            }{
                Message: "Sukses melihat data",
                Data:    *user,
            }
            return c.JSON(http.StatusOK, response)
  19. Setelah selesai menulis seluruhnya. Saatnya melakukan pengujian menggunakan Postman. Terlebih dahulu, jalankan server anda dengan membuka command line lalu masukkan perintah go run server.go

Hasil pengujian rest api adalah sebagai berikut :

  1. Endpoint (user/create_user) POST
  2. Endpoint (user/create_user) POST json
    - Diatas adalah contoh request post method dengan data yang dikirim dalam bentuk json (Content-Type : application/json). Kemudian jika menggunakan Content-Type : multipart/form atau application/x-www-form-urlencoded, maka request-nya adalah seperti gambar dibawah ini :
    Endpoint (user/create_user) POST form
    - Diatas pada field ktp diisi terisi sebuah file yang dikirim. Untuk pengiriman file sendiri, tidak bisa dilakukan dengan Content-Type : application/json.
  3. Endpoint (user/update_user/:email) PUT
  4. Endpoint (user/update_user/:email) PUT
    - Terlihat di endpoint method diatas terdapat parameter email fulan@gmail.com. Parameter inilah yang dibaca go dengan kode c.Param(“email”).
  5. Endpoint (user/delete_user/:email) DELETE
  6. Endpoint (user/delete_user/:email) DELETE
  7. Endpoint (user/search_user) GET
  8. Endpoint (user/search_user) GET
Demikian, hasil yang didapat dari pengujian api menggunakan postman. Untuk source code full dari aplikasi diatas adalah sebagai berikut :
package main

import (
    "fmt"
    "io"
    "net/http"
    "os"
    "strings"

    "github.com/labstack/echo/v4"
)

type Users struct {
    Email       string `json:"email" form:"email"`
    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 main() {
    route := echo.New()
    route.POST("user/create_user", func(c echo.Context) error {
        user := new(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 := struct {
            Message string
            Data    Users
        }{
            Message: "Sukses melakukan penambahan data",
            Data:    *user,
        }
        return c.JSON(http.StatusOK, response)
    })

    route.PUT("user/update_user/:email", func(c echo.Context) error {
        user := new(Users)
        c.Bind(user)
        user.Email = c.Param("email")
        // do something here ....
        response := struct {
            Message string
            Data    Users
        }{
            Message: "Sukses mengupdate data",
            Data:    *user,
        }
        return c.JSON(http.StatusOK, response)
    })

    route.DELETE("user/delete_user/:email", func(c echo.Context) error {
        user := new(Users)
        user.Email = c.Param("email")
        // do something here ....
        response := struct {
            Message string
            ID      string
        }{
            Message: "Sukses menghapus data",
            ID:      user.Email,
        }
        return c.JSON(http.StatusOK, response)
    })

    route.GET("user/search_user", func(c echo.Context) error {
        user := new(Users)
        user.Email = c.QueryParam("keywords")
        user.Nama = "AdityaDS"
        user.ALamat = "Jalan Jalan"
        user.Ktp = "file.jpg"
        // do something here ....
        response := struct {
            Message string
            Data    Users
        }{
            Message: "Sukses melihat data",
            Data:    *user,
        }
        return c.JSON(http.StatusOK, response)
    })

    route.Start(":9000")
}

Untuk tutorial dasar Rest API di Golang Menggunakan Echo Framework cukup sampai disini. 
Read More

https://payclick.com/

Contact us for advertising.