by Abu Zubayr

Rest API di Golang Menggunakan Echo Framework

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 = "Abu Zubayr"
            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 = "Abu Zubayr"
        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. Untuk project ini sendiri juga sudah saya post di github bisa di cek di https://github.com/sardiabuzubayr/simple-echo-restapi.
Semoga bermanfaat, wassalamualaikum warahmatullah wabarakatuh
loading...
Share:

0 Comments:

Post a Comment

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