前回の続きで開発環境構築した go言語用のwebフルスタックフレームワークである beego にあるコード自動作成機能を使ってコードを生成していこうと思います。
scaffold を使ってのコード自動生成
beego にも rails と同じようにコードを自動生成する generate 機能があります。
この中の scaffold で CURD 画面を一括作成しようと思います。
これもまた後述しますが、画面の自動生成はしてくれず、controller も JSON を返す形だったので Rails の scaffold のようなものを期待すると肩透かしを食らうかもしれません。(食らった人)
コマンドの実行
今回はDB立てたりするのはせず、説明もめんどいので
sqlite を使ってサクッとやろうとのはずだったのですが、後述もしてますがサポートできてないみたいなので結果 DB は postgrsql 使ってやっています。
ってことでまずは sqlite ってことで下記コマンドを実行します。
bee generate scaffold post -fields="title:string,body:text" -driver=sqlite
> bee generate scaffold post -fields="title:string,body:text" -driver=sqlite
______
| ___ \
| |_/ / ___ ___
| ___ \ / _ \ / _ \
| |_/ /| __/| __/
\____/ \___| \___| v1.10.0
2018/09/20 10:58:53 INFO ? 0001 Do you want to create a 'post' model? [Yes|No]
y
2018/09/20 10:58:57 INFO ? 0002 Using 'Post' as model name
2018/09/20 10:58:57 INFO ? 0003 Using 'models' as package name
create C:\Users\user\go\src\beegotest\haruch/models/post.go
2018/09/20 10:58:57 INFO ? 0004 Do you want to create a 'post' controller? [Yes|No]
y
2018/09/20 10:58:58 INFO ? 0005 Using 'Post' as controller name
2018/09/20 10:58:58 INFO ? 0006 Using 'controllers' as package name
2018/09/20 10:58:58 INFO ? 0007 Using matching model 'Post'
create C:\Users\user\go\src\beegotest\haruch/controllers/post.go
2018/09/20 10:58:58 INFO ? 0008 Do you want to create views for this 'post' resource? [Yes|No]
y
2018/09/20 10:58:59 INFO ? 0009 Generating view...
create C:\Users\user\go\src\beegotest\haruch/views/post/index.tpl
create C:\Users\user\go\src\beegotest\haruch/views/post/show.tpl
create C:\Users\user\go\src\beegotest\haruch/views/post/create.tpl
create C:\Users\user\go\src\beegotest\haruch/views/post/edit.tpl
2018/09/20 10:58:59 INFO ? 0010 Do you want to create a 'post' migration and schema for this resource? [Yes|No]
y
2018/09/20 10:59:00 FATAL ? 0011 Driver not supported
は?
Driver not supported
https://github.com/beego/bee/blob/e90da8f77bba1050b32ce1c7b9b2461d44252546/generate/g_migration.go#L184
あはは!
サポートしてないなら候補に書くなやあああああ\(^o^)/
ってことで sqlite は諦めて、DBの立て方などは割愛させていただきますが、たまたま今使っている windows 上に postgres が立っていたのでそれを使おうかと思います。
気を取り直して postgres を指定してコマンドを打ちます。
SSL の設定をしていないので sslmode=disable
を指定しています。
> bee generate scaffold post -fields="title:string,body:text" -driver=postgres -conn="postgres://postgres:postgres@127.0.0.1:5432/postgres?sslmode=disable"
______
| ___ \
| |_/ / ___ ___
| ___ \ / _ \ / _ \
| |_/ /| __/| __/
\____/ \___| \___| v1.10.0
2018/09/20 11:53:14 INFO ? 0001 Do you want to create a 'post' model? [Yes|No]
y
2018/09/20 11:53:15 INFO ? 0002 Using 'Post' as model name
2018/09/20 11:53:15 INFO ? 0003 Using 'models' as package name
create C:\Users\user\go\src\beegotest\haruch/models/post.go
2018/09/20 11:53:15 INFO ? 0004 Do you want to create a 'post' controller? [Yes|No]
y
2018/09/20 11:53:16 INFO ? 0005 Using 'Post' as controller name
2018/09/20 11:53:16 INFO ? 0006 Using 'controllers' as package name
2018/09/20 11:53:16 INFO ? 0007 Using matching model 'Post'
create C:\Users\user\go\src\beegotest\haruch/controllers/post.go
2018/09/20 11:53:16 INFO ? 0008 Do you want to create views for this 'post' resource? [Yes|No]
y
2018/09/20 11:53:17 INFO ? 0009 Generating view...
create C:\Users\user\go\src\beegotest\haruch/views/post/index.tpl
create C:\Users\user\go\src\beegotest\haruch/views/post/show.tpl
create C:\Users\user\go\src\beegotest\haruch/views/post/create.tpl
create C:\Users\user\go\src\beegotest\haruch/views/post/edit.tpl
2018/09/20 11:53:17 INFO ? 0010 Do you want to create a 'post' migration and schema for this resource? [Yes|No]
y
create C:\Users\user\go\src\beegotest\haruch/database/migrations/20180920_115320_post.go
2018/09/20 11:53:20 INFO ? 0011 Do you want to migrate the database? [Yes|No]
y
2018/09/20 11:53:25 ERROR ? 0012 Could not build migration binary: exit status 1
2018/09/20 11:53:25 ERROR ? 0013 |> m.exe.go:9:2: cannot find package "github.com/lib/pq" in any of:
2018/09/20 11:53:25 ERROR ? 0014 |> C:\Users\user\go\src\beegotest\vendor\github.com\lib\pq (vendor tree)
2018/09/20 11:53:25 ERROR ? 0015 |> C:\Go\src\github.com\lib\pq (from $GOROOT)
2018/09/20 11:53:25 ERROR ? 0016 |> C:\Users\user\go\src\github.com\lib\pq (from $GOPATH)
2018/09/20 11:53:25 WARN ? 0017 Could not remove temporary file: remove m.exe: The system cannot find the file specified.
質問に y で答えていくと最後なんかライブラリが無いと怒られます。そうですか(´・ω・`)
そしてここまでくるに何度か実は失敗していて、 dep の挙動が怪しく、パッケージが無いとか言われたら dep ensure
を叩きなおしてみるといいかもしれません。
自分が出てたのはなぜか github.com/astaxie/beego/migration
が無いと言われ、もう一度 dep ensure
を叩いたら落ちてきたという謎の現象。
ってことで気を取り直し
> dep ensure -add github.com/lib/pq
Fetching sources...
"github.com/lib/pq" is not imported by your project, and has been temporarily added to Gopkg.lock and vendor/.
If you run "dep ensure" again before actually importing it, it will disappear from Gopkg.lock and vendor/.
足りないライブラリがインストールできたら
> bee migrate -driver=postgres -conn="postgres://postgres:postgres@127.0.0.1:5432/postgres?sslmode=disable"
______
| ___ \
| |_/ / ___ ___
| ___ \ / _ \ / _ \
| |_/ /| __/| __/
\____/ \___| \___| v1.10.0
2018/09/20 13:30:52 INFO ? 0001 Using 'postgres' as 'driver'
2018/09/20 13:30:53 INFO ? 0002 Using 'postgres://postgres:postgres@127.0.0.1:5432/postgres?sslmode=disable' as 'conn'
2018/09/20 13:30:53 INFO ? 0003 Running all outstanding migrations
2018/09/20 13:31:00 INFO ? 0004 |> 2018/09/20 13:30:58.389 [I] start upgrade Post_20180920_115320
2018/09/20 13:31:00 INFO ? 0005 |> 2018/09/20 13:30:58.428 [I] exec sql: CREATE TABLE post(id serial primary key,title TEXT NOT NULL,body TEXT NOT NULL)
2018/09/20 13:31:00 INFO ? 0006 |> 2018/09/20 13:30:58.468 [I] end upgrade: Post_20180920_115320
2018/09/20 13:31:00 INFO ? 0007 |> 2018/09/20 13:30:58.468 [I] total success upgrade: 1 migration
2018/09/20 13:31:00 SUCCESS ? 0008 Migration successful!
最後に失敗してた migrate を実行します。
よかった成功した。
自動生成されたファイルの確認
- databaseフォルダ 配下
migrationフォルダ配下に日付_post.go
中にはinit
up
down
の3つのメソッドが書かれており、init では日付情報などを登録しており、up ではコマンドで指定したスキーマ情報を元にテーブルを作成していました。m.SQL("CREATE TABLE post(id serial primary key,title TEXT NOT NULL,body TEXT NOT NULL)")
のこりの down はロールバック時に使うテーブル削除の SQL が書かれています。
基本的に Rails の migrateファイルと同じような構成と思えば良いと思います。
- modelsフォルダ 配下
直下にpost.go
基本的な DB の書き込みや取得を orm 経由で行うためのメソッドが定義されています。
自動生成してくれてるので別に問題はないのですが Rails の ActiveRecord みたいにモデルさえ定義してしまえばよしなにやってくれるのではなく CURD はある程度コードを書かなきゃいけないのが若干気になりましたが、必要なものは揃っているのでこれらの組み合わせで特に困ることはなさそうです。
逆に言えば DB アクセスへの細かいコードが書かれているのでカスタマイズは容易とも言えるでしょう。 - controllersフォルダ 配下
直下にpost.go
こちらも基本的な REST に基づいたメソッドが自動生成されています。// GetOne ... // @Title Get One // @Description get Post by id // @Param id path string true "The key for staticblock" // @Success 200 {object} models.Post // @Failure 403 :id is empty // @router /:id [get] func (c *PostController) GetOne() { idStr := c.Ctx.Input.Param(":id") id, _ := strconv.ParseInt(idStr, 0, 64) v, err := models.GetPostById(id) if err != nil { c.Data["json"] = err.Error() } else { c.Data["json"] = v } c.ServeJSON() }
メソッドの中を見てみると、見た通りの処理が書いてあるのですが返されるのは JSON 形式となっているため、View との紐付けは自分で実装しなければいけない様子でした。
また、メソッドの上部にコメントで @付きのものがありますが、これらはアノテーションとなっており、メソッドに対してのパラメータやルーティングの設定を行っています。
アノテーションは APIドキュメントを自動生成するためにも使われているようです。
Params と router についてはこちらでも詳しい説明があります。
メソッドのほかにも下記のように URLMapping の記述もありました。
// URLMapping ...
func (c *PostController) URLMapping() {
c.Mapping("Post", c.Post)
c.Mapping("GetOne", c.GetOne)
c.Mapping("GetAll", c.GetAll)
c.Mapping("Put", c.Put)
c.Mapping("Delete", c.Delete)
}
しかしこれ自体を書くことは必須ではなく、前述の @router
アノテーションでルーティングの設定は行われてます。
これを書くことで beego の処理が高速になるそうです。下部参考
- views 配下
create.tpl, edit.tpl, index.tpl, show.tpl の4ファイルがそれぞれ作成されてはいたのですが、中身はファイルパスが書かれているだけでHTMLは生成してくれませんでした。Controller が JSON を返却するだけであったので当然という感じはしますが。
どうやら beego の scaffold は Rails に比べて自動生成力は弱いみたいですね。
ってか View は作成しなければいいのにと思ったり。これからの発展には期待です。
まとめ
自分個人としてコードの自動生成は Rails のものしか使ったことが無かったので、文中にも比較が多くなってしまったのですが、やはり Rails の scaffold 機能は view まで作ってくれるので、すぐwebサービスとして使えるようになり、非常に強力だなぁという感想にどうしてもなってしまいました。
とはいえコントローラーのアノテーションでルーティングをするところや、まだ試してはいませんが指定したアノテーションがそのままAPIのドキュメントを作成するキーになるのは便利なんじゃないかと思いました。
あとは view ファイルを作成するのであればちゃんと HTML も生成してほしかったのと、sqlite 対応してないならコマンドのオプション例に出さないでほしかったなぁってところでしょうかw
次回は自動生成されたコードを参考にしつつ view も作成して実際に view から DB 書き込みと読み出しを行い、webサービスっぽい感じにしていきたいと思います。