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 :</span>=<span style="color: #000000;"> service.baseRepository.InitDBConn()
defer conn.Close()
stmt, err :</span>= conn.Prepare(<span style="color: #800000;">"</span><span style="color: #800000;">INSERT INTO `blog` SET title=?,introduction=?,content=?</span><span style="color: #800000;">"</span><span style="color: #000000;">)
fmt.Println(err)
res, err :</span>=<span style="color: #000000;"> stmt.Exec(blog.Title, blog.Introduction, blog.Content)
fmt.Println(err)
id, err :</span>=<span style="color: #000000;"> res.LastInsertId()
blog.Id </span>= <span style="color: #0000ff;">int</span><span style="color: #000000;">(id)
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> 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 {

}
</span><span style="color: #0000ff;">for</span><span style="color: #000000;"> rows.Next() {
</span><span style="color: #0000ff;">var</span> count <span style="color: #0000ff;">int</span><span style="color: #000000;">
err </span>= rows.Scan(&amp;<span style="color: #000000;">count)
res.TotalCount </span>=<span style="color: #000000;"> count
}
start :</span>= (pageIndex - <span style="color: #800080;">1</span>) *<span style="color: #000000;"> pageSize
sql :</span>= fmt.Sprintf(<span style="color: #800000;">"</span><span style="color: #800000;">SELECT *FROM `blog` ORDER BY creation_date LIMIT %d,%d</span><span style="color: #800000;">"</span><span style="color: #000000;">, start, pageSize)
rows, err </span>=<span style="color: #000000;"> conn.Query(sql)
</span><span style="color: #0000ff;">if</span> err !=<span style="color: #000000;"> nil {
fmt.Println(err)
}
blogList :</span>= make([]domain.Blog, <span style="color: #800080;">0</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">for</span><span style="color: #000000;"> rows.Next() {
element :</span>=<span style="color: #000000;"> domain.Blog{}
err :</span>= rows.Scan(&amp;element.Id, &amp;element.Title, &amp;element.Introduction, &amp;element.Content, &amp;element.ViewCount, &amp;element.Author, &amp;<span style="color: #000000;">element.CreationDate)
</span><span style="color: #0000ff;">if</span> err !=<span style="color: #000000;"> nil {
</span><span style="color: #0000ff;">continue</span><span style="color: #000000;">
}
blogList </span>=<span style="color: #000000;"> append(blogList, element) }
res.Data </span>=<span style="color: #000000;"> blogList
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> 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:<span style="color: #800000;">"</span><span style="color: #800000;">id</span><span style="color: #800000;">"</span><span style="color: #000000;">

Title string param:<span style="color: #800000;">"</span><span style="color: #800000;">title</span><span style="color: #800000;">"</span> //标题

Introduction string param:<span style="color: #800000;">"</span><span style="color: #800000;">introduction</span><span style="color: #800000;">"</span> //简介

Content string param:<span style="color: #800000;">"</span><span style="color: #800000;">content</span><span style="color: #800000;">"</span> //内容

ViewCount int param:<span style="color: #800000;">"</span><span style="color: #800000;">viewCount</span><span style="color: #800000;">"</span> //浏览次数

} type PageRequest struct {

*Mvc.RequestBody

PageIndex int param:<span style="color: #800000;">"</span><span style="color: #800000;">pageIndex</span><span style="color: #800000;">"</span><span style="color: #000000;">

PageSize int param:<span style="color: #800000;">"</span><span style="color: #800000;">pageSize</span><span style="color: #800000;">"</span><span style="color: #000000;"> } ///这里注意参数必须是指针类型

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感兴趣的朋友欢迎在评论区留下宝贵的意见,欢迎帮助我们点一个星星~

YoyoGo使用指南的更多相关文章

  1. JavaScript权威指南 - 函数

    函数本身就是一段JavaScript代码,定义一次但可能被调用任意次.如果函数挂载在一个对象上,作为对象的一个属性,通常这种函数被称作对象的方法.用于初始化一个新创建的对象的函数被称作构造函数. 相对 ...

  2. UE4新手之编程指南

    虚幻引擎4为程序员提供了两套工具集,可共同使用来加速开发的工作流程. 新的游戏类.Slate和Canvas用户接口元素以及编辑器功能可以使用C++语言来编写,并且在使用Visual Studio 或 ...

  3. JavaScript权威指南 - 对象

    JavaScript对象可以看作是属性的无序集合,每个属性就是一个键值对,可增可删. JavaScript中的所有事物都是对象:字符串.数字.数组.日期,等等. JavaScript对象除了可以保持自 ...

  4. JavaScript权威指南 - 数组

    JavaScript数组是一种特殊类型的对象. JavaScript数组元素可以为任意类型,最大容纳232-1个元素. JavaScript数组是动态的,有新元素添加时,自动更新length属性. J ...

  5. const extern static 终极指南

    const extern static 终极指南 不管是从事哪种语言的开发工作,const extern static 这三个关键字的用法和原理都是我们必须明白的.本文将对此做出非常详细的讲解. co ...

  6. Atitit.研发管理软件公司的软资产列表指南

    Atitit.研发管理软件公司的软资产列表指南 1. Isv模型下的软资产1 2. 实现层面implet1 3. 规范spec层1 4. 法则定律等val层的总结2 1. Isv模型下的软资产 Sof ...

  7. HA 高可用软件系统保养指南

    又过了一年 618,六月是公司一年一度的大促月,一般提前一个月各系统就会减少需求和功能的开发,转而更多去关注系统可用性.稳定性和管控性等方面的非功能需求.大促前的准备工作一般叫作「备战」,可以把线上运 ...

  8. 第六代智能英特尔® 酷睿™ 处理器图形 API 开发人员指南

    欢迎查看第六代智能英特尔® 酷睿™ 处理器图形 API 开发人员指南,该处理器可为开发人员和最终用户提供领先的 CPU 和图形性能增强.各种新特性和功能以及显著提高的性能. 本指南旨在帮助软件开发人员 ...

  9. Visual Studio Code 配置指南

    Visual Studio Code (简称 VS Code)是由微软研发的一款免费.开源的跨平台文本(代码)编辑器.在我看来它是「一款完美的编辑器」. 本文是有关 VS Code 的特性介绍与配置指 ...

随机推荐

  1. 如何将别人Google云端硬盘中的数据进行保存

    查了好久终于知道! 如何将别人Google云端硬盘中的数据进行copy,而不是右键发现只有添加快捷方式 只要shift+z就可以保存了! 之后等我弄清楚怎么将别人家的云盘中的数据集导到colab再来详 ...

  2. 自制 os 极简教程1:写一个操作系统有多难

    为什么叫极简教程呢?听我慢慢说 不知道正在阅读本文的你,是否是因为想自己动手写一个操作系统.我觉得可能每个程序员都有个操作系统梦,或许是想亲自动手写出来一个,或许是想彻底吃透操作系统的知识.不论是为了 ...

  3. ubuntu下创建http服务器

    使用ubuntu搭建一个简单的http服务器安装apache21.sudo apt-get update2.sudo apt-get install apache2 安装成功后,再/etc/apach ...

  4. SpringBoot实现文件上传功能详解

    目录 利用SpirngBoot实现文件上传功能 零.本篇要点 一.SpringBoot对文件处理相关自动配置 二.处理上传文件MultipartFile接口 三.SpringBoot+Thymelea ...

  5. create event[]

    一.前言自 MySQL5.1.6起,增加了一个非常有特色的功能–事件调度器(Event Scheduler),可以用做定时执行某些特定任务(例如:删除记录.对数据进行汇总等等),来取代原先只能由操作系 ...

  6. Interface(接口分享)第一节

    一.接口初探 有时候我们传入的参数可能会包含很多的属性,但是编译器只会检查那些必须的属性是否存在,以及类型是否匹配,而咱们要讲的接口其实就是用来描述下面这个例子里的结构,对于接口传入的数据咱们只关心它 ...

  7. react 中组件状态的一些理解

    组件状态:即 state 只有当state发生变化时,组件才会更新. 当一个html标签的值依赖于state的值得时候,如果state的值没有更新时,这个标签的值无论如何也是不会更新的. 看下面示例: ...

  8. putty连接Linux(NAT)

    1.系统装好后第一次连的时候需要打开ssh服务 sudo apt-get install openssh-server 当在机器不能通过ping ip相通的话那么就要解决ip不同的问题,当ip相通还是 ...

  9. cephonebox发布

    前言 现在已经是2016年收官的一个月了,之前一直想做一个calamari的集成版本,之所以有这个想法,是因为,即使在已经打好包的情况下,因为各种软件版本的原因,造成很多人无法配置成功,calamar ...

  10. Mon失效处理方法

    假设环境为三个mon,主机名为mon1.mon2.mon3,现在mon3上面的系统盘损坏,mon的数据完全丢失,现在需要对mon3进行恢复处理 1.停止所有mon进程,可以不停其他进程,需要停止内核客 ...