Edited at

Go製フレームワーク(BEEGO)の使い方


Beego


目次


  1. インストール方法・環境構築

  2. logの出力方法

  3. マイグレーション

自分がいろいろ忘れないように覚書程度に記載

基本的にマニュアルどおりに作っていけばよい。ハチが可愛い

公式サイト

前提:goが使える。

- インストール(環境設定)

- プロジェクト作成

- ルーティング


インストール

go get -u github.com/beego/bee

go get -u github.com/astaxie/beego

以上

cliツールがあり、今回はAPIとしてプロジェクトを作成

#GOPATH/srcのディレクトリの下で下記コマンド

bee api testapi
#自動的に必要なファイルがtestapi下に生成される
cd testapi
#サーバを起動
bee run -downdoc=true -gendoc=true

[http://127.0.0.1:8080/swagger/]

APIドキュメントもいっしょに作成される


設定は下記ファイルにて行う

testapi\conf\app.conf

ただし、アプリ名はなぜかディレクトリ名となってしまう。解決方法がわかる方いたら教えてほしい


環境別の設定の仕方

ここではまった。

ドキュメントには


/conf/app.conf

[dev]

httpport = 8080
[prod]
httpport = 8088
[test]
httpport = 8888

こんな感じで書いてあるが

bee run -runmode=prod とか書いてもデフォルト値が設定され動かない。

すると、config.goにこんな記述が…


config.go

if os.Getenv("BEEGO_RUNMODE") != "" {

filename = os.Getenv("BEEGO_RUNMODE") + ".app.conf"
}}

なるほど、-runmode=prod で起動するときは ファイル名をprod.app.confにすればよいみたい。


/conf/dev.app.conf

[dev]

httpport = 8080


/conf/prod.app.conf

[dev]

httpport = 8088

動いた!ただbee run で実行するときは/conf/app.confが必要


logの出力の仕方

下記を実行

go get github.com/astaxie/beego/logs

import (

"github.com/astaxie/beego/logs"
)
func main() {
// 一般的
l := logs.GetLogger()
l.Println("this is a message of http")

  //ORMのログ
logs.GetLogger("ORM").Println("this is a message of orm")
        
  //デバッグのログ 
logs.Debug("my book is bought in the year of ", 2016)
logs.Info("this %s cat is %v years old", "yellow", 3)
logs.Warn("json is a type of kv like", map[string]int{"key": 2016})
logs.Error(1024, "is a very", "good game")
logs.Critical("oh,crash")
}


Migration:マイグレーション

MySQLの設定

mysql> SELECT user, host, plugin FROM mysql.user;
+------------------+-----------+-----------------------+
| user | host | plugin |
+------------------+-----------+-----------------------+
| mysql.infoschema | localhost | caching_sha2_password |
| mysql.session | localhost | caching_sha2_password |
| mysql.sys | localhost | caching_sha2_password |
| root | localhost | mysql_native_password |
+------------------+-----------+-----------------------+
4 rows in set (0.00 sec)

#やらないとこのエラーが出る
Could not show migrations table: The authentication plugin is not supported.


モデルファイルの作成

beegoのCLIツールで簡単に作れる

bee generate model テーブル名 -fields="name:int"

※-fieldsは適当でよい。後でカラム等は簡単に修正できるため。

bee generate model sample_mst -fields="name:int"`

______
| ___ \
| |_/ / ___ ___
| ___ \ / _ \ / _ \
| |_/ /| __/| __/
\____/ \___| \___| v1.10.0
2019/04/13 04:08:39 INFO ▶ 0001 Using 'Sample_mst' as model name
2019/04/13 04:08:39 INFO ▶ 0002 Using 'models' as package name
create /go/src/xxx/models/sample_mst.go
2019/04/13 04:08:39 SUCCESS ▶ 0003 Model successfully generated!

作成されたファイル↓

(ID)は勝手に挿入される。テーブルのカラムは type Sample_mst struct の部分で再定義すれば問題ない。


/go/src/xxx/models/sample_mst.go

package models

import (
"errors"
"fmt"
"reflect"
"strings"

"github.com/astaxie/beego/orm"
)
//モデル定義
type Sample_mst struct {
Id int64 `orm:"auto"`
Name int
}

func init() {
orm.RegisterModel(new(Sample_mst))
}

// AddSample_mst insert a new Sample_mst into database and returns
// last inserted Id on success.
func AddSample_mst(m *Sample_mst) (id int64, err error) {
o := orm.NewOrm()
id, err = o.Insert(m)
return
}

// GetSample_mstById retrieves Sample_mst by Id. Returns error if
// Id doesn't exist
func GetSample_mstById(id int64) (v *Sample_mst, err error) {
o := orm.NewOrm()
v = &Sample_mst{Id: id}
if err = o.QueryTable(new(Sample_mst)).Filter("Id", id).RelatedSel().One(v); err == nil {
return v, nil
}
return nil, err
}

// GetAllSample_mst retrieves all Sample_mst matches certain condition. Returns empty list if
// no records exist
func GetAllSample_mst(query map[string]string, fields []string, sortby []string, order []string,
offset int64, limit int64) (ml []interface{}, err error) {
o := orm.NewOrm()
qs := o.QueryTable(new(Sample_mst))
// query k=v
for k, v := range query {
// rewrite dot-notation to Object__Attribute
k = strings.Replace(k, ".", "__", -1)
qs = qs.Filter(k, v)
}
// order by:
var sortFields []string
if len(sortby) != 0 {
if len(sortby) == len(order) {
// 1) for each sort field, there is an associated order
for i, v := range sortby {
orderby := ""
if order[i] == "desc" {
orderby = "-" + v
} else if order[i] == "asc" {
orderby = v
} else {
return nil, errors.New("Error: Invalid order. Must be either [asc|desc]")
}
sortFields = append(sortFields, orderby)
}
qs = qs.OrderBy(sortFields...)
} else if len(sortby) != len(order) && len(order) == 1 {
// 2) there is exactly one order, all the sorted fields will be sorted by this order
for _, v := range sortby {
orderby := ""
if order[0] == "desc" {
orderby = "-" + v
} else if order[0] == "asc" {
orderby = v
} else {
return nil, errors.New("Error: Invalid order. Must be either [asc|desc]")
}
sortFields = append(sortFields, orderby)
}
} else if len(sortby) != len(order) && len(order) != 1 {
return nil, errors.New("Error: 'sortby', 'order' sizes mismatch or 'order' size is not 1")
}
} else {
if len(order) != 0 {
return nil, errors.New("Error: unused 'order' fields")
}
}

var l []Sample_mst
qs = qs.OrderBy(sortFields...).RelatedSel()
if _, err = qs.Limit(limit, offset).All(&l, fields...); err == nil {
if len(fields) == 0 {
for _, v := range l {
ml = append(ml, v)
}
} else {
// trim unused fields
for _, v := range l {
m := make(map[string]interface{})
val := reflect.ValueOf(v)
for _, fname := range fields {
m[fname] = val.FieldByName(fname).Interface()
}
ml = append(ml, m)
}
}
return ml, nil
}
return nil, err
}

// UpdateSample_mst updates Sample_mst by Id and returns error if
// the record to be updated doesn't exist
func UpdateSample_mstById(m *Sample_mst) (err error) {
o := orm.NewOrm()
v := Sample_mst{Id: m.Id}
// ascertain id exists in the database
if err = o.Read(&v); err == nil {
var num int64
if num, err = o.Update(m); err == nil {
fmt.Println("Number of records updated in database:", num)
}
}
return
}

// DeleteSample_mst deletes Sample_mst by Id and returns error if
// the record to be deleted doesn't exist
func DeleteSample_mst(id int64) (err error) {
o := orm.NewOrm()
v := Sample_mst{Id: id}
// ascertain id exists in the database
if err = o.Read(&v); err == nil {
var num int64
if num, err = o.Delete(&Sample_mst{Id: id}); err == nil {
fmt.Println("Number of records deleted in database:", num)
}
}
return
}



接続

接続情報は直書してもいいが、/conf/app.confに記載する


/conf/app.conf

//mySQLの設定

mysql_driver = "mysql"
mysql_user = "root"
mysql_password = "password"
mysql_host = "127.0.0.1"
mysql_db = "sample-db"


main.go

package main

import (
"fmt"
_ "xxx/routers" //自分のルータがあれば
"strings"
"time"

"github.com/astaxie/beego"
_ "github.com/go-sql-driver/mysql"
)

func main() {
beego.Run()
}

func init() {
orm.RegisterDriver("mysql", orm.DRMySQL)
driver := beego.AppConfig.String("mysql_driver")
user := beego.AppConfig.String("mysql_user")
pass := beego.AppConfig.String("mysql_password")
host := beego.AppConfig.String("mysql_host")
port := beego.AppConfig.String("mysql_host")
db := beego.AppConfig.String("mysql_db")
datasource := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8", user, pass, host, port, db)
orm.RegisterDataBase("default", driver, datasource, 30)
}



DBを作成するためにやることは2つ。

モデルにorm.RegisterModel(new(モデル))を追加

mainにorm.RunSyncdb("default", false, true)を追加

RegisterModelはテーブルやカラムがなかった場合、作成してくれる


参考にさせていただいたサイト

Go言語のWAF Beegoの紹介