Go初心者向けに始めた記事の第4回になります。
Go初学者がアプリ開発する時に「アプリの起動はビルドファイルを実行するだけでよいのか?」「アプリ起動する時に必要な設定とかはどうするか?」など疑問がうまれると思います。
自分の開発している現場では、基本的にアプリの起動はcobraのCLIを使っていて、環境変数の設定はviperを使用してます。なのでcobra、viperはGo開発者にとって必要な知識になります。
cobra、viperについて
cobraとは
cobraは簡単にCLIを実装できるライブラリ、以下のリンクに書いてあるようにKubernetesにも使われていります。
cobraを使用している理由として、ビルドした1つのバイナリで複数の処理ができることです。
例えば、APIと定期的にバッチを実行する処理2つを別コマンドで動かしたい時に、CLIだとサブコマンドを使用して、APIの起動とバッチの起動を分けることができます。そして起動する時にコマンドのオプションをつけたい場合にも、flagを使用することで容易にできます。
viperとは
環境設定ファイルを簡単にするライブラリ。Viperは様々な設定のニーズとフォーマットに対応し、JSON, TOML, YAMLなどからファイルを読み込んで環境の設定ができる。
cobra、viperを試してみる
インストール
# ライブラリをインストール
go get -u github.com/spf13/cobra@latest
# cobraのCLIをインストール
go install github.com/spf13/cobra-cli@latest
# viperのインストール
go get github.com/spf13/viper
# cobraアプリの初期化をして、実行に必要なファイルが生成されます。
# 色々ファイルが作成されていますが、とりあえずmain.go、cmd/root.goだけを気にしておけば良いです。
cobra-cli init
コード
今回はお試してとして、default.toml or test.tomlのファイルを読み込み、読み込んだ内容を出力するソースを書きました。
tomlファイルの内容は今後DBに接続する時に使用する予定です。
このソースの処理の流れとして、
- init()で初期化処理が動き
- initConfig()で設定ファイルを読み込み、configに設定する
- Execute() からRun: func(~)が呼ばれ、configの中身が出力
という流れになってます。
src/cmd/root.go
/*
Copyright © 2023 NAME HERE <EMAIL ADDRESS>
*/
package cmd
import (
"log"
"os"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
type Config struct {
Type string
Host string
Port int
User string
Password string
Name string
}
var config Config
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "go-column",
Run: func(cmd *cobra.Command, args []string) {
// configの中身を出力
log.Printf("configの中身:{type: %s, host: %s, port: %d, user: %s, pass: %s, name: %s}",
config.Type, config.Host, config.Port, config.User, config.Password, config.Name)
},
}
func Execute() {
err := rootCmd.Execute()
if err != nil {
os.Exit(1)
}
}
func init() {
// 初期化処理
// configの設定
rootCmd.Flags().StringP("configName", "n", "default.toml", "config file name")
// Runを実行するたびに、initConfigを呼び出す。その後に、Runの処理が動き出す。
cobra.OnInitialize(initConfig)
}
func initConfig() {
configName, _ := rootCmd.Flags().GetString("configName")
viper.SetConfigFile(configName)
// 設定ファイルを読み込む
if err := viper.ReadInConfig(); err != nil {
log.Println(err)
os.Exit(1)
}
// 設定ファイルの内容を構造体に設定
if err := viper.Unmarshal(&config); err != nil {
log.Println(err)
os.Exit(1)
}
}
test.toml
type = "mysql"
host = "localhost"
port = 3306
user = "root"
password = "test_pass"
name = "test"
default.toml
type = "mysql2"
host = "localhost2"
port = 3307
user = "default"
password = "default_pass"
name = "default"
Dockerfile
コンテナあげる度に、cobra-cliをインストールする必要があるので、イメージを作成する。
FROM golang:1.19-bullseye
WORKDIR /work
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
wget \
make \
unzip \
git \
clang-format \
vim \
&& apt-get clean
# cobraのCLIをインストール
RUN go install github.com/spf13/cobra-cli@latest
RUN pwd
COPY src/go.mod src/go.sum ./
RUN go mod download && go mod verify
docker-compose.yml
Dockerfileで作成したイメージを見るように修正
version: "3.9"
services:
go-env:
build:
context: .
volumes:
- ./src:/work
working_dir: /work
tty: true
最終的には以下のようなファイル構成になります。
実行結果
フラグの設定がなければ、default.tomlの内容が出力され、フラグが設定されていれば設定されたファイルの内容が出力されてます。
# build
root@80eba8a81cb8:/work# make build
go build .
# フラグなしで、default.tomlの内容が読み込まれていることを確認
root@80eba8a81cb8:/work# ./go-column
2023/05/24 13:11:08 configの中身:{type: mysql2, host: localhost2, port: 3307, user: default, pass: default_pass, name: default}
# フラグにtest.tomlを設定して、test.tomlファイルの内容が読み込まれていることを確認
root@80eba8a81cb8:/work# ./go-column --configName test.toml
2023/05/24 13:12:21 configの中身:{type: mysql, host: localhost, port: 3306, user: root, pass: test_pass, name: test}
まとめ
今回はcobra、viperについて説明をしてきました。
次はGoでAPIを作る方法を紹介していきます。Goの場合はフレームワークを使用せずAPIの開発をすることができるので、その理由とどのように開発をしているか書いてます。興味あればぜひ読んでください。
今回の記事以外にもGoについて書いた記事がございますので、もし興味がありましたら、おすすめ記事も見てもらえたらと思います。
【次の記事】
【おすすめ記事のリンク】
コメント