diskusi.tech (beta) Community

loading...
Lentera Community

Belajar dan Berkenalan dengan Go Embed

riskyferyansyahp profile image Risky Feryansyah ・5 min read

Halo Teman - teman, kalian tahu gak di bahasa pemograman Go versi 1.16 ada beberapa perubahan dan fitur tambahan seperti go:embed, go tools, dll. Nah, di artikel saya kali ini, saya tidak akan membahas satu persatu perubahan ataupun fitur tambahan yang ada pada Go versi 1.16, melainkan kita akan belajar tentang fitur yang baru di perkenalkan oleh Go dan masih release beta version yaitu tentang Go Embedding Files.

Sebelum kita masuk ke materi tentang Go Embedding mungkin lebih bagus kalau kita tahu terlebih dahulu kenapa Go official membuat fitur built-in untuk melakukan embedding.

Sebenarnya sudah banyak sekali library-library external Go yang membuat fitur untuk melakukan Embedding Files, contohnya seperti:

  1. https://github.com/rakyll/statik
  2. https://github.com/knadh/stuffbin
  3. https://github.com/gobuffalo/packr
  4. https://github.com/perkeep/perkeep
  5. https://github.com/shurcooL/vfsgen
  6. dsb

Dan list di atas masih bisa lebih banyak lagi lebih dari 10, nah terus apa alasan Go membuat fitur built-in Embedding sendiri ? Yaitu karena banyaknya library-library diatas dan setiap library di atas memilik proses dan flow sendiri, lalu Go ingin membuat sebuah standarisasi dengan membuat yang namanya Go Embedding Files. Lalu kebanyakan library embedding diatas menggunakan go:generate di mana akan muncul masalah yang menyebabkan bengkaknya git histori ketika melakukan commit hasil file generate.

Lalu apa Goal yang di tawarkan Go Embed ini ?

  1. Go Embed tidak menggunakan go:generate yang artinya tidak akan melakukan generate file
  2. Membiarkan pengguna memilih jenis file / jenis global file akses mana yang akan di butuhkan
  3. Go Embed menggunakan pendekatan directive contohnya (go:embed)

Lumayan banyak juga ya sejarah tentang kenapa kok Go membuat fitur Go Embedding Files 😁. Yuk langsung aja kita masuk perkenalan ke dalam Go Embedding

Apa sih itu Go Embed

Go Embed merupakan suatu fitur bawaan dari Go yang ada sejak versi 1.16, dimana Go Embed ini menyedikan akses langsung kepada file untuk di sematkan secara langsung ke dalam program Go yang sedang berjalan dan bisa di sematkan juga ke dalam binary files hasil build program Go.

Bagaimana cara menggunakan Go Embed

Untuk dapat menggunakan fitur embed ini, pastikan kamu sudah menginstall Go versi 1.16, kalau kalian belum install versi 1.16 kalian bisa download disini.

untuk menggunakanya di dalam Go program hal pertama yang harus kalian lakukan adalah melakukan import package embed, lalu di dalam embed directive hanya mendukung 3 tipe data saja yaitu :

  • String

    Jika kalian menggunakan string, kalian hanya dapat menyematkan satu file saja ketika melakukan embed, contohnya seperti ini:

    package main
    
    import _ "embed"
    
    //go:embed version.txt
    var version string
    

    kode diatas kalian menyematkan file version.txt kedalam variabel version, kalian bisa langsung menampilkan isi dari variabel version tersebut juga.

  • []byte

    Dengan menggunakan tipe []byte, kalian juga hanya dapat menyematkan satu file saja ketika melakukan embed, biasanya tipe []byte ini digunakan ketika kalian ingin menyematkan file-file media seperti file foto, contohnya seperti ini:

    package main
    
    import _ "embed"
    
    //go:embed profile.png
    var profile []byte
    

    kode diatas kalian menyematkan file profile.png kedalam variabel profile, kalian bisa langsung menampilkan isi dari variabel profile tersebut juga.

  • embed.FS (embed.FS ini dia menerapkan interface dari fs.FS)

    Ketika kalian menggunakan tipe embed.FS kalian bisa menyematkan banyak file sekaligus, contohnya seperti ini:

    package main
    
    import "embed"
    
    //go:embed template/*
    var tmpl embed.FS
    

    maksud dari kode di atas, embed directive akan menyematkan semua file yang ada di dalam directory template/ dan di sematkan ke dalam variabel tmpl dengan tipe embed.FS, kalian mungkin bertanya-tanya "kok bisa menggunakan pattern * ? ", kita akan bahas ini bawah.


    Catatan

    Ketika kalian melakukan embed directive (//go:embed), pastikan kalian sudah meng-import package **embed*, dan pastikan baris setelah embed *directive adalah variabel yang menyimpan hasil dari embed file tersebut.


Pattern dalam menyematkan file dengan Go Embed

//go:embed directive menerima beberapa pattern misalnya spasi sebagai pemisahnya, contohnya seperti berikut:

//go:embed template/* image/*
var content embed.FS
Enter fullscreen mode Exit fullscreen mode

Dalam kode di atas kalian melakukan embed semua file yang ada pada directory template dan image, kalian juga bisa menggunakan pattern baris baru (enter) untuk menghindari baris yang sangat panjang ketika di sana banyak sekali yang harus di embed.

Pemisah yang di gunakan //go:embed directive dalam melakukan embed yaitu forward slash (/) dan pattern tidak boleh mengandung (.), (..) ataupun path yang kosong, contohnya seperti template/, ../template atau ./template nah ini tidak di perbolehkan.

Untuk lebih lanjut dalam mempelajari tentang sebuah pattern dari //go:embed directive kalian bisa mengunjungi Go Embed Directive.

Contoh Studi Kasus Membuat Environtment File Load sendiri menggunakan Go Embedding

Pada kesempatan kali ini kita akan mencoba membuat sebuah utility untuk melakukan load dari environment file (.env) tanpa bantuan library apapun melainkan kita akan memanfaatkan Go Embed untuk membuatnya.

  1. Hal pertama yang harus kalian lakukan adalah pastikan Go versi anda menggunakan versi 1.16.
  2. Lakukan go mod init pada root directory project anda (go mod init github.com/username/yyyy) terserah mau pakek nama apapun
  3. Buat file main.go, lalu buat folder baru dengan nama util dan di dalam folder util bikin sebuah file baru dengan nama loadenv.go, contoh struktur project nya nanti akan jadi seperti ini:

    root directory
    β”‚
    └───util
    β”‚   β”‚   loadenv.go
    β”‚   
    β”‚   .env
    β”‚   go.mod
    |   main.go 
    
  4. Isi file .env kalian seperti ini:

    DB_HOST=localhost
    DB_PORT=2222
    DB_USER=root
    DB_PASS=root
    
  5. Didalam file loadenv.go, tuliskan kode seperti berikut:

    package util
    
    import (
        "os"
        "strings"
    )
    
    // LoadEnv doing process split string from file .env
    // and extract each key and value to os environment
    func LoadEnv(env string) {
        s := strings.Split(env, "\n")
    
        for _, v := range s {
            // vS is the new slice of string that split by `=`,
            // the result is always 2 index, first index is key, and the second index is value
            vS := strings.Split(v, "=")
    
            os.Setenv(vS[0], vS[1])
        }
    }
    

    Pada baris ke 11 kita melakukan split ke string yang kita terima sebagai parameter dengan separator nya berdasarkan new line, dan akan menghasilkan nilai slice string baru.

    Lalu pada baris 13 kita melakukan looping ke dalam slice string yang baru kita dapatkan dari split pada baris 11.

    Kemudian pada baris 16 kita melakukan split string lagi tetapi dengan separator kali ini berdasarkan =, disini kita akan menghasilkan 2 index slice string, dimana index pertama akan dijadikan sebagai key nya, dan index ke dua dijadikan sebagai value nya, jika kalian bingung bayangkan kita punya environtment variables seperti ini:

     DB_HOST=localhost
    

    Nah ketika kita melakukan split berdasarkan separator di atas, kita akan menghasilkan slice string ["DB_HOST", "localhost"].

    Lalu pada baris 18 kita melakukan set environment ke dalam program Go kita dengan memanfaatkan package os.

Langkah terakhir, isikan kode berikut ke dalam file main.go

package main

import (
    _ "embed" // import embed but not used
    "fmt"
    "os"

    "github.com/username/yyyy/util"
)

//go:embed .env
var env string

func main() {
    util.LoadEnv(env)

    fmt.Println("DB_HOST", os.Getenv("DB_HOST"))
    fmt.Println("DB_PORT", os.Getenv("DB_PORT"))
    fmt.Println("DB_USER", os.Getenv("DB_USER"))
    fmt.Println("DB_PASS", os.Getenv("DB_PASS"))
}
Enter fullscreen mode Exit fullscreen mode

Kalian bisa lihat disana pada baris 4 kita melakukan import pada package embed dan pada baris 11 kita melakukan embed directive untuk meng-embed file .env ke dalam variabel env kita bertipe string.

Pada baris 15 kalian memanggil function LoadEnv dengan melemparkan variabel env kita yang bertipe string untuk di proses.

Dan pada baris 17 - 20 kita menampilkan semua environment variable yang sudah di-set di Go program yang kita buat.

Tamat

Sekian teman-teman yang bisa saya sampaikan tentang Go Embed dan contoh untuk studi kasus yang dapat di implementasikan menggunakan Go Embed.

Kalau kalian ingin mempelajari lebih dalam tentang Go Embed kalian bisa langsung baca dokumentasi nya disini, bisa juga kalian membaca source code core dari Go Embed nya disini.

Terimakasih buat kalian yang sudah meluangkan waktu untuk membaca tulisan saya ❀️ πŸ˜ƒ.

Semoga kalian di beri kesehatan selalu dan di lancarkan rezeki nya.

Discussion

pic
Editor guide