Go にも“rails g scaffold”を：爆速CLIツール「gon」の紹介

Go でアプリケーションを開発していると、毎回同じようなパッケージ構造・ファイル名・初期実装を書くことに疲れてきませんか？

Rails には `rails generate scaffold` という便利なコマンドがあります。これがあるおかげで、開発者は構造を気にせず「まずは作る」ことに集中できます。

**そんな体験を Go にも持ち込めないか？**\
そう思って作ったのが、CLI ツール `gon` です。

https://github.com/mickamy/gon

---

## ✪ gon ってなに？

`gon` は、Rails のように 1 コマンドで model、use-case、handler を生成できる、意見の強い Go 向けの scaffold ツールです。

```bash
gon g scaffold User name:string email:string
```

これを叩くだけで、以下のような構造が生成されます：

```
internal/
└── domain/
    └── user/
        ├── model/
        ├── repository/
        ├── usecase/
        ├── handler/
        └── fixture/
```

クリーンアーキテクチャに基づいた構成で、ディレクトリごとにパッケージも分けています。

---

## ✨ gon の特徴

- Rails ライクなコマンドで爆速開発
- model, usecase, や handler を一度に生成
- クリーンアーキテクチャ準拠のディレクトリ構成
- テストコードや fixture も自動で生成
- テンプレートは `embed` ベースでカスタマイズ可能

---

## 🔧 インストール

Go 1.17+ なら以下でインストールできます：

```bash
go install github.com/mickamy/gon@latest
```

Go 1.24+ の場合は `go get -tool` でもOK：

```bash
go get -tool github.com/mickamy/gon
```

初期化とテンプレートの準備は次の 2 ステップです：

```bash
gon init     # gon.yaml を作成
gon install  # テンプレートとテストヘルパーを準備
```

---

## ✨ 実際に使ってみる

### modle の生成

```bash
gon g model User name:string email:string
```

### use-case の追加

```bash
gon g usecase CreateUser
```

### handler の生成

```bash
gon g handler User list create
```

### ぜんぶ一括で

```bash
gon g scaffold User name:string email:string
```

このコマンドを実行すると、以下のようなファイルが自動生成されます：

```
internal/
└── domain/
    └── user/
        └── fixture/
        │   └── user.go
        ├── model/
        │   └── user_model.go
        ├── usecase/
        │   ├── create_user_use_case.go
        │   ├── get_user_use_case.go
        │   ├── list_user_use_case.go
        │   ├── update_user_use_case.go
        │   └── delete_user_use_case.go
        ├── repository/
        │   └── user_repository.go
        └── handler/
            └── user_handler.go
```

削除もできます：

```bash
gon d scaffold User
```

---

## 🧱 「意見の強さ」が gon の魅力

gon は柔軟性よりも、「迷わず使える」ことを重視しています。\
ディレクトリ構成や命名規則を統一することで、チーム開発でも迷子になりません。

テンプレートは `embed` されており、必要なら `gon install` 後にカスタマイズも可能です。

---

## 🧩 作成されるコードの一例

実際に作成されるコードの一部をご紹介します。

### handler（ListUserHandler）

```go
type ListUserHandler echo.HandlerFunc

func ListUser(uc usecase.ListUser) ListUserHandler {
	return func(c echo.Context) error {
		ctx := c.Request().Context()
		output, err := uc.Do(ctx, usecase.ListUserInput{})
		if err != nil {
			return c.JSON(http.StatusInternalServerError, err)
		}
		return c.JSON(http.StatusOK, output)
	}
}
```

### usecase（CreateUser）

```go
package usecase

import (
	"context"
)

type CreateUserInput struct {}

type CreateUserOutput struct {}

//go:generate mockgen -source=$GOFILE -destination=./mock_$GOPACKAGE/mock_$GOFILE -package=mock_$GOPACKAGE
type CreateUser interface {
	Do(ctx context.Context, input CreateUserInput) (CreateUserOutput, error)
}

type createUser struct {}

func NewCreateUser() CreateUser {
	return &createUser{}
}

func (uc createUser) Do(ctx context.Context, input CreateUserInput) (CreateUserOutput, error) {
	return CreateUserOutput{}, nil
}
```

### repository（User）

```go
package repository

// ...

func (repo *user) List(ctx context.Context, scopes ...func(*gorm.DB) *gorm.DB) ([]model.User, error) {
	var m []model.User
	err := repo.db.WithContext(ctx).Scopes(scopes...).Find(&m).Error
	return m, err
}
// 他のメソッドは省略
```

## 🤪 例を見てみたい？

[`example/`](https://github.com/mickamy/gon/tree/main/example) ディレクトリに、gon を使ったサンプルアプリを置いています。ぜひ覗いてみてください。

---

## 🔭 今後の展望

- DI ライブラリへの対応
    - google/wire を想定
- http request/response につめる DTO の生成
- gorm/echo 以外のライブラリ対応
- より洗練されたアーキテクチャへの改造

など、いろいろアイデアがあります。Issue や PR も歓迎しています！

---

## 🙏 最後に

`gon` は「Go でも Rails みたいに開発したい！」という思いから生まれました。
ぜひ試して、フィードバックをもらえると嬉しいです。