Sejak golang vesi 1.16, terdapat package baru bernama embed. Package embed adalah fitur baru untuk mempermudah membaca isi file pada saat compile time secara otomatis dimasukkan isi file nya ke dalam variable. Untuk detailnya bisa di review pada laman https://pkg.go.dev/embed
Untuk melakukan embed ke variable, kita bisa mengimport package embed terlebih dahulu. Selanjutnya kita bisa tambahkan komentar //go:embed
di ikuti dengan nama file nya, diatas variable yang kita tuju, variable yang dituju tersebut nanti secara otomatis akan berisi konten file yang kita inginkan secara otonatis ketika kode golang di compile. Dan variable yang dituju tidak bisa disimpan di dalam function, artinya variable harus di luar function.
Embed file ke string
Embed file bisa kita lakukan ke variable dengan tipe data string, secara otomatis isi file akan dibaca sebagai text dan dimasukkan ke variable tersebut.
Untuk mencobanya, buatlah project baru dengan nama belajar-golang-embed
kemudian inisialisasi project sebagai module dengan go mod init belajar-golang-embed
. Selanjutnya buat file abru di dalam project tersebut dan beri nama version.txt
dan isikan : 1.0.0-SNAPSHOT

Setelah membuat file txt yang akan di embed, selanjutnya buat unit test baru dengan nama embed_test.go
dan masukkan baris kode berikut
package belajar_golang_embed
import (
_ "embed"
"fmt"
"testing"
)
//go:embed version.txt
var version string
func TestString(t *testing.T) {
fmt.Println(version)
}

Pada baris kode diatas, kita melakukan embed di baris ke 9 dan menyimpan hasil nya ke variable version
di baris ke 10, dan kita melakukan print ke layar di baris ke 13. Saat melakukan embed jangan lupa untuk melakukan import package embed nya seperti di baris ke 4.
Embed file ke []byte
Selain ke tipe data string, embed file juga bisa dilakukan ke variable tipe data []byte
. Ini cocok sekali jika kita ingin melakukan embed file dalam bentuk binary, seperti gambar dan lain-lain.
Pertama siapkan sebuah gambar, disini saya sudah menyiapkan gambar dengan nama logo.png
dan sudah disimpan pada project yang sebelumnya di buat.

Jika sudah menyiapkan logo, langkah selanjutnya buatlah unit test baru dengan nama TestByte()
dan masukkan baris kode berikut
//go:embed logo.png
var logo []byte
func TestByte(t *testing.T) {
err := os.WriteFile("logo_new.png", logo, fs.ModePerm)
if err != nil {
panic(err)
}
}

Pada kode program diatas, sama seperti sebelumnya kita melakukan embed di baris 1 ke variable logo
pada baris 2, yang berbeda adalah tipe datanya, jika sebelumnya string
, maka saat ini kita menggunakan []byte
untuk menampung file logo.png
. Nah setelah file tersimpan di variable, selanjutnya pada baris ke 5 kita melakukan copy file logo.png
ke file baru dengan nama logo_new.png
. Cobalah jalankan kode program diatas dan pastikan file nya sudah tercopy.
![Output embed []byte](https://nos.jkt-1.neo.id/archive.rendyuwu.my.id/2022/09/output-logo-1024x452.png)
Bisa di perhatikan jika file png nya sudah tercopy dan hasilnya sama, artinya ktia sudah berhasil melakukan embed file gambar ke variable.
Embed multiple files
Kadang ada kebutuhan kita melakukan embed beberapa file sekaligus, hal ini juga bisa dilakukan menggunakan embed package. Kita bisa menambahkan komentar //go:embed
lebih dari satu baris, selain itu variable nya bisa kita gunakan tipe data embed.FS
Contohnhya, buatlah folder abru terlebih dahulu dengan nama files
kemudian buat juga 3 file baru di folder tersebut dengan nama a.txt, b.txt & c.txt
yang masing-masing isinya simple saja yaitu AAA, BBB & CCC
.
Selanjut nya buat unit test baru dengan nama TestMultipleFiles()
dan isikan baris kode berikut ini
//go:embed files/a.txt
//go:embed files/b.txt
//go:embed files/c.txt
var files embed.FS
func TestMultipleFiles(t *testing.T) {
a, _ := files.ReadFile("files/a.txt")
fmt.Println(string(a))
b, _ := files.ReadFile("files/b.txt")
fmt.Println(string(b))
c, _ := files.ReadFile("files/c.txt")
fmt.Println(string(c))
}

Pada kode program diatas, kita melakukan embed dengan beberapa baris dari baris ke 1-3 dan kita masukkan ke variable files
di baris 4. Dan untuk mengakses nya bisa kita lakukan ReadFile
seperti baris ke 7, 10 & 13.
Path matcher
Selain manual satu persatu, kita bisa menggunakan path matcher untuk membaca multiple file yang kita ingin kan. Ini sangat cocok ketika misal kita punya pola jenis file yang kita ingin kan untuk kita baca. Caranya, kita perlu menggunakan path matcher seperti pada package function path.Match
.
Berikut contoh penggunaan path matcher
package belajar_golang_embed
import (
"embed"
"fmt"
"io/fs"
"os"
"testing"
)
//go:embed files/*.txt
var path embed.FS
func TestPathMatcher(t *testing.T) {
dirEntries, _ := path.ReadDir("files")
for _, entry := range dirEntries {
if !entry.IsDir() {
fmt.Println(entry.Name())
file, _ := path.ReadFile("files/" + entry.Name())
fmt.Println(string(file))
}
}
}

Pada kode program diatas, setalah kita melakukan embed dengan path matcher pada baris 11, untuk mengambil nama dan isi konten nya kita melakukan iterasi di baris ke 16. Dan pengambilan konten atau isi nya sendiri sebenar nya sama seperti sebelumnya, contoh nya seperti pada baris ke 19.
Hasil embed di compile
Perlu diketahui, bahwa hasil embed yang dilakukan oleh package embed adalah permanentdan data file yang dibaca disimpan dalam binary file golang nya. Artinya bukan dilakukan secara realtime membaca file yang ada di luar. Hal ini menjadikan jika binary file golang sudah di compile, kita tidak butuh lagi file external nya, dan bahkan jika diubah file external nya, isi variable nya tidak akan berubah.
Penutup
Pada artikel kali ini kita telah belajar tentang embed pada bahasa pemrogaman go. Dan pada artikel selanjutnya saya akan membahas tentang golang web pada bahasa pemrogaman go.