<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # Baa 工程化 所謂工程化,不是baa的功能,而是在使用baa的過程中總結出的一種姿勢,姑且稱之為:最佳實踐。 按照一般MVC的開發規范,一個程序通常會有 數據模型、模板視圖、業務控制,輔助的還要有 前端資源文件,應用配置文件,可能還要記錄日志文件。 ## 目錄結構 ``` project |-- conf |-- app.ini |-- controller |-- index.go |-- article.go |-- user.go |-- data |-- log |-- model |-- base |-- base.go |-- cache.go |-- base.go |-- article.go |-- user.go |-- module |-- util |-- util.go |-- template |-- template.go |-- public |-- assets |-- css |-- images |-- js |-- upload |-- robots.txt |-- router |-- init.go |-- router.go |-- template |-- share |-- header.html |-- footer.html |-- article |-- index.html |-- show.html |-- user |-- show.html |-- index.html |-- main.go |-- README.md ``` 結構說明 | 路徑 | 說明 | 備注 | |-----------------------------|--------------|--------| | conf | 配置文件目錄 | -- | | conf/app.ini | 應用配置文件 | [setting](https://github.com/go-baa/setting) 配置庫要求的配置文件路由 | controller | 業務控制器目錄 | -- | | controller/*.go | 具體控制器 | 建議每個功能一個控制器文件 | | data | 數據目錄 | -- | | data/log | 日志目錄 | 建議路徑,可在配置文件中指定 [log](https://github.com/go-baa/log) 輸出路徑 | | model | 數據模型目錄 | -- | | model/base | 數據模型基類 | 提供對于數據庫連接,緩存連接等基礎操作 | | model/base.go | 模型基類 | 導入 `model/base` 初始化數據庫,是其他模型的基礎 | | model/article.go | 業務模型 | 具體的業務模型,建議每個表對應一個模型文件,命名和表名一致 | | module | 擴展功能模塊 | -- | | module/util | 助手模塊 | 一些常用的功能函數,文件操作,URL操作,加解密等 | | module/util/util.go | 助手函數 | 常用函數庫 | | module/template | 模板擴展 | -- | | module/template/template.go | 模板函數庫 | 結合 [render](https://github.com/go-baa/render) 模板引擎,可以擴展模板函數 | | public | 靜態資源目錄 | -- | | public/assets | 前端資源目錄 | -- | | public/assets/css,images,js | 前端文件目錄 | -- | | public/uplaod | 上傳文件目錄 | -- | | public/robots.txt | 靜態文件 | 其他靜態文件,可以放在資源目錄下 | | router | 路由設定目錄 | -- | | router/init.go | baa初始化 | 初始化baa,加載中間件,模板組件,緩存組件等 | | router/router.go | 路由配置 | 獨立了路由配置在一個文件中,結構更清晰 | | template | 模板目錄 | -- | | template/share | 共享目錄 | 存儲共享的模板片段 | | template/article | 業務模板 | 具體的業務模板,建議和控制一一對應,每個控制一個目錄,每個方法一個文件 | | template/index.html | 首頁模板 | 應用的首頁文件 | | main.go | 應用入口 | -- | | README.md | 應用說明 | -- | 完整結構,參見示例 [blog](https://github.com/go-baa/example/tree/master/blog) ## 控制器 控制器中按業務劃分成了不同的文件,不同的操作還應該有不同的方法對應,在實現上有兩種考慮: - 一個控制器中所有方法都是函數,使用控制器的名字作為函數名前置防止多個控制中的命名沖突。 - 將一個控制器視為一個類,所有方法都是類的方法,雖然Go中沒有明確的類,但也可以實現面向對象編程。 兩種聲音都有支持,你可以根據自己喜歡來做,我們選擇了第二種姿勢,看起來更舒服一些。 最終,一個控制文件可能是這樣的: ``` // api/controller/index.go package controller import ( "github.com/go-baa/example/api/model" "github.com/go-baa/log" "gopkg.in/baa.v1" ) type index struct{} // IndexController ... var IndexController = index{} // Index list articles func (index) Index(c *baa.Context) { page := c.ParamInt("page") pagesize := 10 rows, total, err := model.ArticleModel.Search(page, pagesize) if err != nil { output(c, 1, err.Error(), nil) return } log.Debugf("rows: %#v, total: %d\n", rows, total) output(c, 0, "", map[string]interface{}{ "total": total, "items": rows, }) } .... ``` > 該文件來自示例程序 [api](http://github.com/go-baa/example/tree/master/api) 為了實現面向對象,創建了一個空的結構體作為方法的承載,所有方法都注冊給這個結構體。 **需要解釋的一句是,為什么還要聲明一個 `IndexController` 呢?** 路由注冊時需要將每一個URL對應到具體的方法上來,結構體的方法是不能直接用的,需要先聲明一個結構體實例才能使用。 在哪兒聲明呢?一個是路由注冊的時候,一個是控制器定義的時候,我們選擇了在控制器定義的時候聲明,作為控制器開發的一個規范,路由定義時引入包就可以用了。 ## 數據模型 baa本身不提供數據模型的處理,在 [api](http://github.com/go-baa/example/tree/master/api) 示例中使用的是 [grom](http://jinzhu.me/gorm/) 來操作MySQL。 [xorm](http://xorm.io/) 和 [grom](http://jinzhu.me/gorm/) 有什么區別呢?論功能 `xorm` 可能更強大一些,我們覺得 `grom` 使用更舒服一些。 雖然他們都做了很好的封裝,但一個項目畢竟還要配置數據庫信息,數據庫連接,還要各種包調用,顯然我們還是要做個簡單的封裝才好。 具體的代碼不列出,請參考 [api/model](http://github.com/go-baa/example/tree/master/api/model) 中的base處理。 在這個基礎上,一個數據模型可能長這個樣子: ``` // api/model/user.go package model // User user data scheme type User struct { ID int `json:"id" gorm:"primary_key; type:int(10) UNSIGNED NOT NULL AUTO_INCREMENT;"` Name string `json:"name" gorm:"type:varchar(50) NOT NULL DEFAULT '';"` Email string `json:"email" gorm:"type:varchar(100) NOT NULL DEFAULT '';"` } type userModel struct{} // UserModel single model instance var UserModel = new(userModel) // Get find a user info func (t *userModel) Get(id int) (*User, error) { row := new(User) err := db.Where("id = ?", id).First(row).Error return row, err } // Create create a user func (t *userModel) Create(name, email string) (int, error) { row := new(User) row.Name = name row.Email = email err := db.Create(row).Error if err != nil { return 0, err } return row.ID, nil } ``` > 該文件來自示例程序 [api](http://github.com/go-baa/example/tree/master/api) 基本思想和控制器是一樣的,先按照表結構聲明一個結構體。然后創建一個空結構體將模型的方法進行封裝,最后聲明了一個 `UserModel`使得在控制器中無需聲明就可以直接使用模型。 **需要注意的是,在模型中每個方法的最后一個參數一定是`error`,表示操作是否出錯,不要問為什么,規范,還是規范,這里講的都是規范。** ## 配置文件 應用配置文件,只能是 `conf/app.ini`,這個由項目 [setting](https://github.com/go-baa/setting) 決定,為什么把路徑寫死了呢,為了省事,無論在哪兒引入包就能用,無需配置和傳遞。 更多的配置文件也建議放在 `conf` 目錄中,自己去讀取。 配置示例: ``` // conf/app.ini [default] # app app.name = baaBlog app.version = 0.1 app.url = "" debug = false # http http.address = 0.0.0.0 http.port = 80 http.access_open = off # output log to os.Stderr log.file = os.Stderr # 0 off, 1 fatal, 2 panic, 5 error, 6 warn, 10 info, 11 debug log.level = 11 # development mode overwrite default config [development] debug = true # production mode overwrite default config [production] debug = false ``` > 再次說明,這個配置文件依賴 [setting](https://github.com/go-baa/setting) 項目。 ## 模板 模板最簡單,按著結構放就好了。 模板的初始化和使用,參考: * [模板渲染](https://github.com/go-baa/doc/tree/master/zh-CN/context.md#模板渲染) * [模板語法](https://github.com/go-baa/doc/tree/master/zh-CN/context.md#模板語法) * [模板接口](https://github.com/go-baa/doc/tree/master/zh-CN/context.md#模板接口) * [render](https://github.com/go-baa/doc/tree/master/zh-CN/component/render.md) * [pongo2](https://github.com/go-baa/doc/tree/master/zh-CN/component/pongo2.md) 項目示例,參考: * [blog](https://github.com/go-baa/example/tree/master/blog) ## 靜態資源 如果是一個API項目,可能沒有靜態資源,忽略就行。 一般的靜態資源,放在那里就好了,然后注冊靜態資源目錄: ``` // router/router.go app.Static("/assets", "public/assets", false, nil) app.StaticFile("/robots.txt", "public/robots.txt") ``` 如果你的項目采用了前端構建的姿勢,那么你就構建吧,和baa也沒什么關系,也不影響, 就是建議把構建后的資源放置到 `public`下面,比如:`public/assets/build` 然后注冊靜態目錄,開發過程中的文件不建議放在 `public`下,因為是不可訪問資源。 ## 打包發布 Go程序的一個好處就是,`go build`然后生成一個二進制文件,Copy到服務上就行了。 不過需要注意的是,按照以上介紹的姿勢,你還要帶上 `配置文件`,`模板`,`靜態資源`,最后運行的目錄應該是這樣的: ``` project |-- conf |-- app.ini |-- public |-- assets |-- build |-- css |-- images |-- js |-- robots.txt |-- template |- share |-- article |-- show.html |-- index.html |-- project // 二進制文件 ``` 至于你的發布姿勢,是什么發布系統都沒關系,要注意,打包的環境和運行的系統環境要一致,mac下編譯出來的,linux可不一定能運行。 > PS:我們發布時采用 gitlab + jenkins 構建 Docker鏡像的方式。 ### 運行 **運行?** 就是 `./project` 就可以了。哦,別忘了設置環境變量: ``` BAA_ENV=production ``` **優雅重啟?** Go1.8就要提供了,之前無論用什么方案都不可避免的要損失一些正在執行的連接。 我們目前采用的是多機部署,上線時,分批進行,保證服務有損但不下線。 ### 依賴管理 依賴管理的工具有很多,我們目前使用的是 [godep](https://github.com/tools/godep),我們將產生的`Godeps`目錄上傳到了git中,確保構建時的環境一致。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看