Marketing Solution Division所属のエンジニアの井上です。
これまでARISE Techbogでは基礎的なGo言語(以下Go)記事を公開してきました。
【Go言語入門】「Go」の概要や特徴とは?社内のAPI開発プロジェクトで採用して分かったこと
【Go言語入門】goroutineとは? 実際に手を動かしながら goroutineの基礎を理解しよう!
今回はGoの応用編としてAPIサーバーを開発をする際に使う便利なツールを紹介していきます。
サンプルのコードもありますのでぜひお楽しみください。
GoでAPIを開発する際の問題
過去の記事でGoはコンパイラ言語であると紹介しました。
しかしAPIサーバーを開発する際に「ソースコードの変更をする度にビルドする必要がある」
そこで開発されたのがAirです。
本記事ではそんなAirを用いたAPIサーバー開発環境の構築方法を紹介します。
本記事のゴール
docker-compose up コマンドを実行するとAPIサーバーが起動する。
ソースコードを変更したときに自動で再ビルドして変更が反映される。
サンプルのコードはこちら。 https://github.com/ariseanalytics/air_sample
構築
実行条件
Go v1.20
Gin v1.9.0 (GoのHTTPフレームワーク、本記事での説明は割愛します)
Air v1.43.0
Docker v23.0.5
docker-compose v2.17.3
各ファイルの紹介
ディレクトリ構成
.
├── Dockerfile
├── .air.toml
├── docker-compose.yaml
├── go.mod
├── go.sum
├── main.go
Dockerfile
FROM golang:1.20.4-bullseye
RUN go install github.com/cosmtrek/air@latest
コンテナにgoコマンドを利用してairをインストールします。
docker-compose.yaml
version: "3.8"
services:
go:
container_name: air_sample
volumes:
- ./:/project/
working_dir: /project
tty: true
build: "./"
ports:
- 8080:8080
command: sh -c 'go mod tidy && air'
コンテナを起動したらGoで用いるパッケージのインポートとAirの起動を行います。
.air.toml
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"
[build]
args_bin = []
bin = "./tmp/main"
cmd = "go build -o ./tmp/main ."
delay = 0
exclude_dir = ["assets", "tmp", "vendor", "testdata"]
exclude_file = []
exclude_regex = ["_test.go"]
exclude_unchanged = false
follow_symlink = false
full_bin = ""
include_dir = []
include_ext = ["go", "tpl", "tmpl", "html"]
include_file = []
kill_delay = "0s"
log = "build-errors.log"
poll = false
poll_interval = 0
rerun = false
rerun_delay = 500
send_interrupt = false
stop_on_error = false
[color]
app = ""
build = "yellow"
main = "magenta"
runner = "green"
watcher = "cyan"
[log]
main_only = false
time = false
[misc]
clean_on_exit = false
[screen]
clear_on_rebuild = false
keep_scroll = true
.air.tomlはAirの設定ファイルであり air init
で生成したファイルをそのまま利用します。
簡単に説明をすると
-
“_test” を含むファイルと”assets”, “tmp”, “vendor”, “testdata” ディレクトリはビルドの対象外とする
-
tmp/ ディレクトリにmainという実行ファイルをビルドして実行する
という設定にしています。
go.mod, go.sum
これらはgoが自動で生成するファイルのため内容は省略します。
$ go mod init <プロジェクト名>
$ go mod tidy
を実行して作成しました。
main.go
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
r.Run()
}
Ginのドキュメントのクイックスタートに記載のサンプルコードをそのまま記述しました。
Ginのデフォルトの設定では8080ポートでリクエストを待ち受けるように設定されているため、main.goを実行すると8080番ポートにリクエストをするとレスポンスが返ってきます。
動作チェック
HTTPサーバーが起動するか
コンテナを起動するためにdocker compose up
を実行します。
$ docker compose up
[+] Running 1/0
✔ Container air_sample Created 0.0s
Attaching to air_sample
air_sample |
air_sample | __ _ ___
air_sample | / /\ | | | |_)
air_sample | /_/--\ |_| |_| \_ , built with Go
air_sample |
~中略~
air_sample | [GIN-debug] Listening and serving HTTP on :8080
このようにHTTPサーバーが起動しました。 実際にリクエストを実行するとレスポンスが返ってくることが確認できます。
$ curl localhost:8080/ping
{"message":"pong"}
air_sample | [GIN] 2023/05/10 - 04:35:23 | 200 | 367.667µs | 172.18.0.1 | GET "/ping"
ホットリロードが機能するか
main.goを下記のように変更し上書き保存をしてみます。
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong updated",
})
})
r.Run()
}
air_sample | main.go has changed
building...
running...
~中略~
[GIN-debug] Listening and serving HTTP on :8000
と表示され再ビルドとAPIの再起動が行われました。
レスポンスの確認をしてみると
$ curl localhost:8080/ping
{"message":"pong updated"}
最後に
今回はGoの応用事例としてAPIサーバーの開発に使う便利なツールを紹介しました。
我々の開発でも重宝しているツールなのでGoでAPIサーバーを構築する際にはぜひ使ってみてください。
最後まで読んでくださりありがとうございました。
今後も近年ホットな技術の記事もアップしていきますので見に来てください!