YoyoGo是一個使用Golang編寫的一個簡單、輕量、快速、基於依賴注入的微服務框架,目前依然在研發階段,歡迎Star以及一起參與到框架的研發
GitHub地址:https://github.com/yoyofx/yoyogo
例子源代碼:https://github.com/yoyofxteam/YoyoBlog.git 請先下載源碼,在查看指南體驗更加~
本文通過一套最為基本的增刪改查,來實例應該如何在最短的時間內最輕松的使用YoyoGo創建出一個自己的Web應用
本文開發環境及依賴版本:
OS: Windows10 企業版
GoLang SDK: go1.15.5 windows/amd64
IDE: GoLand 2020
YoyoGo: v1.5.8
MySQL: 5.7
MySQL_Deiver: v1.5.0
現在開始我們的造物之旅 o(*////▽////*)q
一、安裝YoyoGo
go為我們自帶了包管理 go get ,會從github幫我們下載依賴,但是由於總所周知的復雜原因,我們需要為自己的本地配置一下加速
go env -w GOPROXY=https://goproxy.cn,direct
打開GoLand ->new Project -->go modules

打開命令行,輸入:
go get github.com/yoyofx/yoyogo

成功的話會出現上圖的結果,如果超時請檢查自己是否成功的配置了加速,檢查方式為:go env 查看GOPRIXY選項

二、啟動Host,完成Hello World
創建main主函數在函數中輸入以下golang代碼
package main import ( YoyoGo "github.com/yoyofx/yoyogo/WebFramework" "github.com/yoyofx/yoyogo/WebFramework/Context" "github.com/yoyofx/yoyogo/WebFramework/Router" ) func main() { YoyoGo.CreateDefaultBuilder(func(router Router.IRouterBuilder) { router.GET("/info",func (ctx *Context.HttpContext) { ctx.JSON(200, Context.H{"msg": "Hello World"}) }) }).Build().Run() //默認端口號 :8080 }
啟動main函數,框架打印出進程ID和監聽端口號,Host啟動成功

我們使用PostMan訪問一下我們在上面代碼中創建的路由,Host返回Hello World,到這一步恭喜你完成了自己的第一個YoyoGo的Web應用的創建~( ̄▽ ̄~)(~ ̄▽ ̄)~

當然,這么簡單的功能是不能滿足我們的,接下里我們要完成一個單表的增刪改查來更加深入的了解YoyoGo的使用
三、編寫配置文件
一個正常的Web框架是肯定需要一個配置文件來保存它的相關配置的,YoyoGo使用golang編寫,我們基於雲原生的基調采用了YAML文件格式座位我們的配置文件格式
首先我們在根目錄下創建一個名為:config_dev.yml的文件,文件名可以隨意編寫,后綴標識當前環境是開發還是生產,我們在文件中輸入以下配置,接下來文件中的各個配置我們都會在后面用到
yoyogo: application: name: Blogs #應用名 metadata: "develop" #當前env server: type: "fasthttp" #Server類型 address: ":8081" #監聽端口 path: "" max_request_size: 2096157 #最大請求體限制 mvc: template: "v1/{controller}/{action}" #路由規則 database: url: tcp(localhost:3306)/yoyoBlog?charset=utf8&parseTime=True #數據庫連接字符串 username: root password: 1234abcd
四、連接數據庫
連接數據庫首先要獲取數據庫驅動
go get github.com/go-sql-driver/mysql
然后我們要從上面的配置文件中讀取出配置文件的數據庫配置節點,進行連接,在YoyoGo中,讀取配置文件配置使用的接口是:Abstractions.IConfiguration,通過使用Iconfiguration的get方法讀取去配置文件的內容,語法為“xxx.xxx.xxx
我們通過構造函數初始化一下這個接口的實例,至於是如何實現構造函數初始化的這個是YoyoGo的依賴注入實現的,到后面我們會演示講解
import ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysql" "github.com/yoyofx/yoyogo/Abstractions" "strings" ) type BaseRepository struct { config Abstractions.IConfiguration } func NewBaseRepository(config Abstractions.IConfiguration) *BaseRepository { return &BaseRepository{config: config} } //初始化一個連接對象 func (baseRepository *BaseRepository) InitDBConn() *sql.DB { url := fmt.Sprint(baseRepository.config.Get("yoyogo.database.url")) ” username := fmt.Sprint(baseRepository.config.Get("yoyogo.database.username")) password := fmt.Sprint(baseRepository.config.Get("yoyogo.database.password")) var sb = strings.Builder{} sb.WriteString(username) sb.WriteString(":") sb.WriteString(password) sb.WriteString("@") sb.WriteString(url) connStr := sb.String() fmt.Println(connStr) conn, err := sql.Open("mysql", connStr) if err != nil { fmt.Println(err) } return conn }
五、對數據庫進行新增和查詢
這部分代碼比較枯燥,唯一需要注意的依然是通過構造函數來進行BaseRepository的注入
import ( "fmt" "yoyoFxBlog/domain" "yoyoFxBlog/repository/repository_impl" ) type BlogService struct { baseRepository *repository_impl.BaseRepository } func NewBlogService(baseRepository *repository_impl.BaseRepository) *BlogService { return &BlogService{baseRepository: baseRepository} } func (service *BlogService) AddLog(blog domain.Blog) domain.Blog { conn := service.baseRepository.InitDBConn() defer conn.Close() stmt, err := conn.Prepare("INSERT INTO `blog` SET title=?,introduction=?,content=?") fmt.Println(err) res, err := stmt.Exec(blog.Title, blog.Introduction, blog.Content) fmt.Println(err) id, err := res.LastInsertId() blog.Id = int(id) return blog } func (service *BlogService) QueryBlogList(pageIndex int, pageSize int) domain.Page { conn := service.baseRepository.InitDBConn() defer conn.Close() res := domain.Page{} rows, err := conn.Query("SELECT COUNT(0) as count FROM `blog` ") if err != nil { } for rows.Next() { var count int err = rows.Scan(&count) res.TotalCount = count } start := (pageIndex - 1) * pageSize sql := fmt.Sprintf("SELECT *FROM `blog` ORDER BY creation_date LIMIT %d,%d", start, pageSize) rows, err = conn.Query(sql) if err != nil { fmt.Println(err) } blogList := make([]domain.Blog, 0) for rows.Next() { element := domain.Blog{} err := rows.Scan(&element.Id, &element.Title, &element.Introduction, &element.Content, &element.ViewCount, &element.Author, &element.CreationDate) if err != nil { continue } blogList = append(blogList, element) } res.Data = blogList return res }
六、創建控制器
首先我們創建一個控制器和幾個接口,創建控制器要注意以下幾點:
1.所有控制器必須和 Mvc.ApiController的指針進行組合
2.為了從請求中抓取參數,我們使用到了go的tag特性,獲取參數的格式為 `param:"arg"` 注意參數名要用雙引號包裹,切用於進行參數綁定的結構體必須和 *Mvc.Requst組合
3.接口中用於進行自動綁定的結構體必須是指針類型
4.通過控制器的名稱前綴來實現HTTP請求類型的限制,例如 GETXXX即為只能使用Get請求
import ( "github.com/yoyofx/yoyogo/WebFramework/ActionResult" "github.com/yoyofx/yoyogo/WebFramework/Mvc" "yoyoFxBlog/domain" "yoyoFxBlog/service" ) type BlogController struct { *Mvc.ApiController blogService *service.BlogService } func NewBlogController(blogService *service.BlogService) *BlogController { return &BlogController{blogService: blogService} } //聲明用於從請求中自動綁定參數的結構體 type BlogRequest struct { *Mvc.RequestBody //必須添加標識可以自動綁定 Id int `param:"id"` Title string `param:"title"` //標題 Introduction string `param:"introduction"` //簡介 Content string `param:"content"` //內容 ViewCount int `param:"viewCount"` //瀏覽次數 } type PageRequest struct { *Mvc.RequestBody PageIndex int `param:"pageIndex"` PageSize int `param:"pageSize"` } ///這里注意參數必須是指針類型 func (controller *BlogController) AddBlog(blog *BlogRequest) ActionResult.IActionResult { data := controller.blogService.AddLog(domain.Blog{Id: blog.Id, Title: blog.Title, Introduction: blog.Introduction, Content: blog.Content, ViewCount: blog.ViewCount}) return ActionResult.Json{Data: data} } //使用GET開頭限制這個接口只能使用GET請求方式 func (controller *BlogController) GetBlogList(PageRequest *PageRequest) ActionResult.IActionResult { data := controller.blogService.QueryBlogList(PageRequest.PageIndex, PageRequest.PageSize) return ActionResult.Json{Data: data} } func (controller *BlogController) BlogList(PageRequest *PageRequest) ActionResult.IActionResult { data := controller.blogService.QueryBlogList(PageRequest.PageIndex, PageRequest.PageSize) return ActionResult.Json{Data: data} }
七、自定義Host啟動依賴注入
划重點,在這一步我們初始化了配置文件,以及控制器和通過調用我們前幾步定義的構造函數來實現依賴的注入
import (
"github.com/yoyofx/yoyogo/Abstractions"
"github.com/yoyofx/yoyogo/DependencyInjection"
YoyoGo "github.com/yoyofx/yoyogo/WebFramework"
"github.com/yoyofx/yoyogo/WebFramework/Mvc"
"yoyoFxBlog/controller"
"yoyoFxBlog/repository/repository_impl"
"yoyoFxBlog/service"
)
func main() {
webHost := CreateYoyoBlogBuilder().Build()
webHost.Run()
}
func CreateYoyoBlogBuilder() *Abstractions.HostBuilder {
//讀取配置文件
configuration := Abstractions.NewConfigurationBuilder().AddYamlFile("config").Build()
return YoyoGo.NewWebHostBuilder().
UseConfiguration(configuration).
Configure(func(app *YoyoGo.WebApplicationBuilder) {
//配置我們上一步寫好的Controller
app.UseMvc(func(builder *Mvc.ControllerBuilder) {
builder.AddController(controller.NewBlogController)
})
}).
//配置我們之前幾步中定義好的構造函數來進行注入
ConfigureServices(func(serviceCollection *DependencyInjection.ServiceCollection) {
serviceCollection.AddTransient(repository_impl.NewBaseRepository)
serviceCollection.AddTransient(service.NewBlogService)
})
}
關於IOC生命周期,我們暫時提供了單例和瞬時兩種方式使用方法為:
func ConfigBusiness(serviceCollection *DependencyInjection.ServiceCollection) {
//瞬時
//直接注入一個容器
serviceCollection.AddTransient(repository_impl.NewBaseRepository)
//為注入的容器起一個名字,類似於Spring中為 Bean命名
serviceCollection.AddTransientByName("NewBaseRepository",repository_impl.NewBaseRepository)
//用接口的形式進行注入,用於一個接口多種實現的情況
serviceCollection.AddTransientByImplements(repository_impl.NewBaseRepository, new(repository.BaseRepository))
//單例
serviceCollection.AddSingleton(repository_impl.NewBaseRepository)
serviceCollection.AddSingletonByName("NewBaseRepository",repository_impl.NewBaseRepository)
serviceCollection.AddTransientByImplements(repository_impl.NewBaseRepository, new(repository.BaseRepository))
}
最后,啟動項目,訪問我們剛才定義的接口,如果你能看到下圖結果,恭喜你,你已經陳工掌握了YoyoGo的基本入門使用!(o゜▽゜)o☆[BINGO!]

感謝一路看到這里的各位,對YoyoGo感興趣的朋友歡迎在評論區留下寶貴的意見,歡迎幫助我們點一個星星~
