Go(v1.23.5)によるWeb API サーバーのローカル開発環境を構築する
はじめに
はじめまして、otot_devです。
Go の環境構築記事の 3 記事目で、↑の記事の続編として、ローカル開発環境を構築したので備忘録として記事を書きました。
概要
一般的に使用されるであろう、API サーバーのローカル環境を構築します。
Go の Web API サーバーと mariadb(MySQL)の構築します。
最終的なアウトプット
今回のコード一式は以下の URL にあります。
v1.1.0 からの全量差分は↓で確認できます。
バージョン情報
-
go
:v1.23.5 -
air-verse/air
:v1.61.7 -
go-delve/delve
: v1.24.0 -
gin-gonic/gin
:v1.10.0 -
jinzhu/gorm
:v1.9.16 -
joho/godotenv
:v1.5.1 -
golang-migrate/migrate/v4
:v4.18.2
一部のフレームワークやライブラリ紹介
gin-gonic/gin
(通称 Gin)は、Go により書かれた軽量で高速な Web フレームワークです。
主な特徴
- 高速: net/http のラッパーであり、内部で Radix ツリーを使用した効率的なルーティングを採用
- ミドルウェア: 認証、ロギング、エラーハンドリングなどを簡単に追加可能
- JSON の扱いが簡単: リクエスト/レスポンスの JSON バインディングが直感的
シンプルな API サーバーを構築するのに適しているようです。
jinzhu/gorm
(通称 GORM)は、Go 言語向けの強力な O/R マッパ(Object-Relational Mapper)ライブラリです。
主な特徴
- シンプルな API: Go の構造体を使ってデータベース操作が直感的にできる
- リレーション管理: One-to-Many, Many-to-Many などの関連付けをサポート
- トランザクション: Begin, Commit, Rollback で簡単に制御可能
SQL を直接書かずに Go の構造体を使ってデータベースを操作できるため、Go での Web 開発に広く使われています。
golangci/golangci-lint
Go 言語向けの高速で拡張性のある静的解析ツールです。
主な特徴
- コード品質向上: コードのバグやスタイル違反を早期に発見
- カスタマイズ可能: .golangci.yml で有効/無効にするルールを設定可能
- CI/CD との統合: GitHub Actions や GitLab CI などに簡単に組み込み可能
Go プロジェクトの品質を維持するために、ほぼデファクトスタンダードとして使われています。
ディレクトリ構成
さっと Web API サーバーを構築したかったので、あまりアーキテクチャの構成は気にしせず作ってあります。詳細は Github のコードを見てください。
.
├── app
│ ├── constants
│ ├── domain
│ ├── infrastructure
│ ├── interfaces
│ │ ├── controllers
│ │ └── database
│ └── usecase
├── migrations
├── seeds
│ └── seeds
└── tests
└── manual
主要ファイルの紹介
構成には記載がない主要なファイルを紹介したいと思います。
Dockerfile
Dockerfile は仮想環境を立ち上げるために必要な主要ファイルですね。
# v1.23.5
FROM golang:1.23-alpine
WORKDIR /app
# v1.61.7
RUN go install github.com/air-verse/air@latest
# v1.24.0
RUN go install github.com/go-delve/delve/cmd/dlv@latest
COPY go.mod go.sum ./
RUN go mod download
# v1.10.0
RUN go get github.com/gin-gonic/gin \
# v1.9.16
github.com/jinzhu/gorm \
github.com/jinzhu/gorm/dialects/mysql \
# v1.5.1
github.com/joho/godotenv
# v4.18.2
RUN go install -tags 'mysql' github.com/golang-migrate/migrate/v4/cmd/migrate@latest
CMD ["air", "-c", ".air.toml"]
docker-compose.yml
Web API サーバーとして api コンテナ(go-api)、RDB として db コンテナ(go-db)を起動するように設定しています。
services:
api:
container_name: go-api
build:
context: .
dockerfile: Dockerfile
ports:
- 8080:3000
- 2345:2345 # リモートデバッグ用
volumes:
- ./:/app
depends_on:
- db
db:
container_name: go-db
image: mariadb:10
platform: linux/x86_64
ports:
- '3306:3306'
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: sample
TZ: 'Asia/Tokyo'
volumes:
- sample-db:/var/lib/mysql
volumes:
sample-db:
driver: local
.air.toml
air はホットリロードするために必要です。
dockerでgoのホットリロード環境を爆速で構築するの記事でも書いたのですが、以下の air 起動時のコマンド設定をすることでホットリロードできます。go-api
コンテナのports → 2345:2345
の設定も重要です。2345 ポートを起点として air を起動させています。
# Customize binary, can setup environment variables when run your app.
- full_bin = "APP_ENV=dev APP_USER=air ./tmp/main"
+ full_bin = "APP_ENV=dev APP_USER=air dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec --continue ./tmp/main"
.golangci.yml
Go 言語向けの高速で拡張性のある静的解析ツールです。これがあることにより、開発時のコード品質を一定に保つことができます。
linters:
enable-all: true
disable:
- varnamelen # variable name 'x' is too short for the scope of its usage
- forbidigo # use of `fmt.Printf` forbidden by pattern `^(fmt\.Print(|f|ln)|print|println)$`
- godot # Comment should end in a period
- nonamedreturns # named return "xxxx" with type "[]xxxx.xxxx" found
- gosmopolitan # string literal contains rune in Han script
- wsl # assignments should only be cuddled with other assignments
- depguard # package "github.com/xxxx/xxxx" is not allowed
- revive
- stylecheck
- predeclared
- gofumpt
- gci
- exportloopref
skip-dirs:
# 羅列したディレクトリはlinterが実行されない
# -
skip-files:
# 羅列したファイルはlinterが実行されない
# -
linters-settings:
# https://github.com/ldez/tagliatelle?tab=readme-ov-file#examples-1
tagliatelle:
case:
rules:
json: snake
.vscode/launch.json
VS code を使用している方限定にはなりますが、デバッグ実行する際に使用する launch.json ファイルです。
{
"version": "0.2.0",
"configurations": [
{
"name": "Go Debug",
"type": "go",
"request": "attach",
"mode": "remote",
"port": 2345
}
]
}
実際に動かしてみる
Docker
# バックグラウンド実行の場合
% docker compose up -d
# ログ出力あり実行の場合
% docker compose up
Go Modules
Go モジュールの依存関係を整理するコマンドです。
% go mod tidy
Database Migration
構築した db コンテナに対して、go-api コンテナからマイグレーションを実行し、その後、seed データの投入します。
% docker exec -it go-api sh
% migrate -database 'mysql://root:password@tcp(go-db:3306)/sample' -path migrations up
% migrate -database 'mysql://root:password@tcp(go-db:3306)/sample' -path migrations down
% go run seeds/seeder.go
Linting
Go プロジェクト内のコードを静的解析し、問題(バグ、非推奨な記述、コードスタイル違反、...etc)を確認します。
% golangci-lint run
% golangci-lint run --fix
Discussion