本記事ではGoの人気なフレームワークの1つであるBeegoを用いていろんなタイプの簡単なアプリを作成し、その過程でBeegoの特徴を解説します。最後に使用感とBeegoが向いている開発について考察します。
対象読者
- Beegoとはなんぞやの人
- Beegoの主要機能を一通り理解したい人
- Beegoを軽く動かしてみたい人
Beegoとは
BeegoはGoで書かれたフルスタックのフレームワークです。
RESTful API、Webアプリ、バックエンドサービスなどのアプリケーションを迅速に作成することができます。
また、Beegoにはbeeというcliツールがあります。beeを用いることで、プロジェクトを生成したりホットリロード機能をオンにしたりと、より効率的にアプリケーションを作成することができます。
環境構築
Beego
まずはインストール。以下のコマンドを実行します。
go get github.com/beego/beego/v2@latest
Beegoはこれで終わり。
bee
cliツールも使えるようにしていきます。
まずは同様にインストール。これにより<your_main_gopath>/bin
配下にbeeバイナリがインストールされます。
go install github.com/beego/bee/v2@latest
続いて、以下のコマンドを実行してbeeバイナリがあるディレクトリを環境変数に登録します。
export PATH=$PATH:<your_main_gopath>/bin
GOPATHの確認方法
your_main_gopath
の部分は以下のコマンドで確認できます。
$ go env GOPATH
最後に、以下のコマンドにて現在のプロジェクトに依存関係を追加します。
go get github.com/beego/bee/v2
bee version
を実行して以下のようになればOK。
$ bee version
2025/05/15 12:34:07.408 [D] init global config instance failed. If you do not use this, just ignore it. open conf/app.conf: no such file or directory
______
| ___ \
| |_/ / ___ ___
| ___ \ / _ \ / _ \
| |_/ /| __/| __/
\____/ \___| \___| v2.3.0
├── GoVersion : go1.23.4
├── GOOS : linux
├── GOARCH : amd64
├── NumCPU : 16
├── GOPATH :
├── GOROOT : /usr/local/go
├── Compiler : gc
└── Date : Thursday, 15 May 2025
開発
GETリクエストに「Hello World!」を返すだけのアプリ
まずはcliツールであるbeeを用いずに開発してみます。
GETリクエストを投げると「Hello World!」を返す簡単なアプリを作成します。
プロジェクト直下にmain.go
を作成し、以下の内容を記述します。
package main
import (
"log"
"github.com/beego/beego/v2/server/web"
beecontext "github.com/beego/beego/v2/server/web/context"
)
func logMiddleware(ctx *beecontext.Context) {
log.Printf("Request: %s %s", ctx.Request.Method, ctx.Request.URL)
log.Printf("IP: %s", ctx.Input.IP())
}
func main() {
web.InsertFilter("/*", web.BeforeRouter, logMiddleware)
web.Get("/", func(ctx *beecontext.Context) {
ctx.Output.Body([]byte("Hello, World!"))
})
web.Run()
}
注目すべきはインスタンス生成がない部分です。
Goの他のフレームワークであるGinやEchoと違い、Beegoではデフォルトでサーバインスタンスweb.BeeApp
がグローバルに用意されています。
そのため、1つのサーバを用いる場合はGinやEchoのように最初にNew()
を実行してサーバインスタンスを作成する必要がありません。
(よりコード量が少なくなるのでいいなと思いつつ、Beegoを触る前にGinやEchoを触っていた自分からするとちょっと違和感あった。)
ただ必要ないだけでGinやEchoのNew()
に相当する関数であるweb.NewHttpServer()
があります。
つまり
web.Get("/", handler)
web.Run()
は、実際には以下のような操作をしています。
server := web.BeeApp.Handlers
server.Get("/", handler)
web.BeeApp.Run()
その他の部分は他のフレームワークとよく似ています。
Get()
でルートパスに対してハンドラを設定しています。
また、今回はルーティング前に送信元のIPアドレスをログとして表示するミドルウェア的な処理を挟むのにInsertFiler()
を用いています。
Beegoではミドルウェア的な処理の実現にFilter
を用いる方法とMiddleware
を用いる方法があります。
それぞれの定義は以下の通りです。
Filter
type FilterFunc = HandleFunc
type HandleFunc func(ctx *beecontext.Context)
Milldeware
type MiddleWare func(http.Handler) http.Handler
Filterの登録にはInsertFiler()を用い、第一引数に与えたルートへのリクエストにのみ処理が実行されます。
一方でMiddlewareの登録はRun()を用います。これによりアプリ全体の共通処理として処理が登録されます。
種類 | 用途 | 特徴 | 主な用途例 |
---|---|---|---|
Filter | ルーティング前後やコントローラ実行前後など、リクエスト処理の特定のタイミングで処理を挟みたい場合に使う | URLパターンやタイミング(BeforeRouter, BeforeExec, AfterExecなど)を細かく指定できる InsertFilterで登録し、FilterFunc型で実装 Beego独自のルーティングやコントローラの仕組みと密接に連携 |
認証・認可 パラメータのバリデーション レスポンスの加工 特定のパスだけに適用したい処理 |
Middleware | Goの標準的なhttp.Handlerチェーンとして、アプリ全体のリクエスト処理の前後に共通処理を挟みたい場合に使う | サーバ起動時(Runメソッド)にMiddleWare型で登録 すべてのリクエストに対して一律に適用される Goの標準的なミドルウェアパターンと互換性が高い |
ロギング CORS対応 全体的なリクエスト・レスポンスのラッピング サードパーティ製ミドルウェアの利用 |
使い分け方として特定のURLやタイBingで処理を挟みたい場合はFilter、アプリ全体に共通の処理を挟みたい場合はMiddlewareを用いると覚えておけば問題ないかと思います。
テストしてみます。アプリを起動したのちにcurlコマンドでGETリクエストを投げてみます。
$ curl localhost:8080
Hello, World!
正しいレスポンスが返ってきました。
MVCアプリ
続いてbeeを用いて簡単なMVCアプリを作成します。
具体的には/users/:idにGETリクエストを投げると該当するユーザの情報を含むHTMLを返すMVCアプリを作成します。
以下のコマンドを実行してプロジェクトを新規作成します。
bee new beegoapp
作成したプロジェクトにはすでにMVCアプリのひな型が作成されています。
次に、以下のコマンドを実行し、User Modelを作成します。
bee generate model User -fields="Name:string,Age:int,Email:string"
今回はユーザ情報として以下の情報を想定しています。
- 名前:Name(string)
- 年齢:Age(int)
- メールアドレス:Email(string)
-fields
オプションを用いることで、自動でこれらのフィールドを持つモデルを作成してくれます。
今回はGetUserById()
だけ用います。
DBは用いないのでダミーデータを返すように修正します。
func GetUserById(id int64) (v *User, err error) {
users := map[string]*User{
"1":{Id: 1, Name: "John", Age: 30, Email: "john@example.com"},
"2":{Id: 2, Name: "Bob", Age: 25, Email: "bob@example.com"},
}
key := fmt.Sprintf("%d", id)
if user, ok := users[key]; ok {
return user, nil
}
return nil, errors.New("User not found")
}
続いて、以下のコマンドを実行し、User Controllerを作成します。
bee generate controller User
controllers
配下にuser.go
が作成されているはずです。便利ですね。
今回はGetOne()
だけ用います。
以下のように修正します。
func (c *UserController) GetOne() {
idStr := c.Ctx.Input.Param(":id")
id, err := strconv.ParseInt(idStr, 10, 64)
if err != nil {
c.CustomAbort(400, "Invalid user id")
return
}
user, err := models.GetUserById(id)
if err != nil {
c.CustomAbort(404, err.Error())
return
}
c.Data["User"] = user
c.TplName = "user/show/show.tpl"
}
ルータの設定を行います。init()
を以下のように修正します。
func init() {
beego.Router("/users/:id", &controllers.UserController{}, "get:GetOne")
}
最後にビューを作成します。
以下のコマンドを実行し、show.tpl
を作成します。
bee generate view user/show
tplというのはtempleteの略です。
BeegoではGo標準の html/template パッケージを使って、動的にHTMLを生成するためのテンプレートファイルとして .tpl 拡張子を使うのが慣例とされています。
show.tpl
を以下のように修正します。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>User Info</title>
</head>
<body>
<h1>User Info</h1>
<p><strong>ID:</strong> {{.User.Id}}</p>
<p><strong>Name:</strong> {{.User.Name}}</p>
<p><strong>Age:</strong> {{.User.Age}}</p>
</body>
</html>
これで完成です。
ブラウザからlocalhost:8080/users/1
にアクセスしてみます。
ユーザ情報が取得できました。
実はbee generate scaffold
を用いれば、今回のように個別でmodel, view, controllerを作らなくても一気に作成することもできます。ぜひ試してみて下さい。
またMVCアプリと同様の手順でRESTful APIも簡単に作ることもできます。こちらもぜひ試してみてください。
感想
今回は簡単なアプリを作りながらBeegoの使い方について記載しました。
以下、実際に使ってみて感じたことです。
cliツールの自動生成が便利
- bee new、bee generate scaffold などで MVC構造を一発で作れるのは、Gin や Echo にはない大きな利点
- CRUDベースのWebアプリの原型を数分で構築可能
グローバルなwebオブジェクトによる手軽な定義
- Beego では web.Get() などで直接ルーティングを定義可能
- gin.New() や echo.New() でインスタンスを生成する必要がないため、コード量が少なくすむ
MVC志向が強く、他のフレームワークと差別化されている
- Gin や Echo は Router ベース(ミニマル志向)で、自分で設計を組む必要がある
- Beego は 明確なMVC設計(Model / Controller / View) が用意されていて、フルスタック志向
結論:こんなときにBeegoが向いている!
- CRUDベースの管理アプリをすばやく作りたいとき
- Goでフルスタック(MVC + HTMLテンプレート)開発をしたいとき
- CLIでベースアプリを一発生成して時短したいとき
- Laravel や Rails のような構造に慣れている人