LoginSignup
0
1

Go言語でConfigファイルをビルド時に埋め込む方法: embedパッケージの活用

Posted at

はじめに

Go言語の強みの一つにポータブル性があります。
Go言語はビルドをするとシングルバイナリになるため、ビルドしたバイナリをコンテナやらサーバーに持ち運ぶだけで簡単に実行できます。

多くのアプリケーションでは設定情報などをコンフィグファイルとして外出ししている場合がありますが、そのような場合はビルドしたバイナリファイルはコンフィグファイルに依存してしまって、デプロイ時にコンフィグファイルも一緒に持ち運ぶ必要が出てきます。

しかしgo:embedを使うことでコンフィグファイルもビルド時にバイナリに含めることができてしまうのです!

前提

  • go1.16以上

ディレクトリ構成

プロジェクト全体を見たい人はGitHubに公開していますのでそちらをご覧ください

コンフィグファイルの埋め込み方法

config/config.jsoon
{
  "logLevel": "DEBUG",
  "server": {
    "host": "localhost",
    "port": 8080
  }
}

今回はこのようなJSON形式の設定ファイルをバイト配列型の変数rawConfigに埋め込みます。

embedパッケージをブランクインポートして、埋め込みたい変数にgo:embed <ファイル名>とコメントをするだけでファイルをバイナリとして埋め込むことができます。

import _ "embed"

//go:embed config.json
var rawConfig []byte

これでビルド時にrawConfigconfig.jsonの中身が反映されます。

構造体に変換する

せっかくなので、埋め込んだJSONを構造体に変換して表示するところまでやってみましょう。

config/config.go
package config

import (
	_ "embed"
	"encoding/json"
	"log"
)

//go:embed config.json
var rawConfig []byte

type Config struct {
	LogLevel string       `json:"logLevel"`
	Server   ServerConfig `json:"server"`
}

type ServerConfig struct {
	Host string `json:"host"`
	Port uint   `json:"port"`
}

func (cfg Config) String() string {
	m, err := json.Marshal(cfg)
	if err != nil {
		log.Fatalln(err)
	}

	return string(m)
}

func Load() (Config, error) {
	cfg := new(Config)
	if err := json.Unmarshal(rawConfig, cfg); err != nil {
		return Config{}, err
	}

	return *cfg, nil
}

rawConfigはJSON形式のデータなのでjson.Unmarshal()を使って構造体に変換できます。

String()メソッドは読み込んだConfigを表示する際に見やすくするためにStringer Interfaceを実装しているだけなので気にしなくてOKです。

config.goの実装が終わったら、実際に出力してみましょう。

main.go
package main

import (
	"demo/config"
	"log"
)

func main() {
	cfg, err := config.Load()
	if err != nil {
		log.Fatalln(err)
	}
	log.Printf("config=%s", cfg)
}

動作確認

以下のコマンドでビルドすると、./build/show-configというバイナリが生成されます。

$ go build -o ./build/show-config ./main.go

生成されたバイナリを実行するとちゃんとconfig.jsonの内容が反映されていることがわかります。

$ ./build/show-config
2023/10/14 15:53:42 config={"logLevel":"DEBUG","server":{"host":"localhost","port":8080}}

さいごに

go:embedを活用して設定ファイルをビルド時のバイナリに含める方法を紹介しました。
今回はJSONを例に紹介しましたが、サードパーティのパッケージを使えばYAMLで記述された設定ファイルも同様に扱えると思います。

今回の記事が少しでも参考になれば幸いです。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1