regin是一款基于go-gin框架封装的web框架,用于快速构建web应用和后端服务.

网友投稿 1360 2022-10-25

regin是一款基于go-gin框架封装的web框架,用于快速构建web应用和后端服务.

regin是一款基于go-gin框架封装的web框架,用于快速构建web应用和后端服务.

regin框架

regin是一款基于go-gin框架封装的web框架,用于快速构建web应用和后端服务.

目录

安装与配置快速开始项目结构路由配置服务配置Web应用数据库RedisUtils工具config文件解析器(支持json、ini)加密算法类型处理(自定义类型、基本类型转换)验证器curl文件操作...

安装与配置

1. 安装Go (version 1.10+), 然后可使用下面命令进行安装regin

$ go get github.com/go-touch/regin

2. 设置系统环境变量

REGIN_RUNMODE = dev | test | prod

3. 依赖包安装(已安装可忽略)

$ go get github.com/gin-gonic/gin$ go get github.com/unrolled/secure$ go get github.com/go-sql-driver/mysql$ go get github.com/garyburd/redigo/redis$ go get gopkg.in/ini.v1

4. 如使用go mod包依赖管理工具, 请参考下面命令

Windows 下开启 GO111MODULE 并设置 GOPROXY 的命令为:

$ set GO111MODULE=on$ go env -w GOPROXY=https://goproxy-,direct

MacOS 或者 Linux 下开启 GO111MODULE 并设置 GOPROXY 的命令为:

$ export GO111MODULE=on$ export GOPROXY=https://goproxy-

快速开始

入口文件: xxx/main.go (xxx 代表项目名称,后面也是)

package mainimport ( "github.com/go-touch/regin" _ "xxx/application/router")func main() { regin.Guide.HttpService()}

$ go run main.go或者:$ go build main.go$ ./xxx

项目结构

application modules // action存放目录, demo // 模块名 model bussiness // 业务类common // 公共处理函数dao // 抽象数据模型form // 校验数据模型mysql // mysql表字段映射模型redis // redis数据模型 router // 注册路由, 主要通过map存储modules对应的action实例的映射 config dev // 必要配置项(通过系统环境变量选择配置路径) database.iniserver.iniredis.ini testprod runtime log // 存储系统错误日志 main.go // 入口文件

路由配置

举例: xxx/application/router/demo.go

package routerimport ( "github.com/go-touch/regin/base" "mygin/application/modules/api/role" "mygin/application/modules/demo")func init() { base.Router.General("demo", base.GeneralMap{ "v1.index": &demo.Index{}, // demo包下的action:Index "role.checkapi": &role.CheckApi{}, // role包下的action:CheckApi })}

访问:http://127.0.0.1/module/controller/action示例:http://127.0.0.1/demo/v1/indexhttp://127.0.0.1/demo/role/checkapi

Note: regin中的路由比较松散,url中pathinfo采用三段路径, 通过获取三段路由信息,使用 . 拼接作为key,读取路由map里面对应的action(action定义可查看web应用介绍). 因此路径的含义可依据路由配置定义,并无严格规定.

服务配置

配置项 xxx/config/server.ini

; 主配置[main]httpHost = 127.0.0.1:8080 // http服务地址端口httpsHost = 127.0.0.1:443 // https服务地址端口; 错误配置[error]log = true // 是否开启错误日志读取format = {date}-Error // 日志文件名格式pattern = local // 日志存储方式 local:本地 remote:远程

项目中使用配置

读取方式: (不会直接获取对应值,而是返回一个regin的configValue结构体指针,可实现对应类型转换)config := service.App.GetConfig("xxx.xxx.xxx")调用示例:config := service.App.GetConfig("server.main.httpHost").ToString()备注: server.ini、database.ini、redis.ini等必要配置项,文件和字段名均为regin使用,不可修改.

Web应用

基类action的代码示例: regin/base/app.action.go

package base// action接口type AppAction interface { BeforeExec(request *Request) (result *Result) // 调用方法 Exec 前执行, 可通过其实现token验证、鉴权等业务 Exec(request *Request) (result *Result) // 用于实现具体的业务逻辑}// action接口的一个实现type Action struct { AppAction}// Before action methodfunc (a *Action) BeforeExec(request *Request) (result *Result) { return}// Action method.func (a *Action) Exec(request *Request) (result *Result) { return}

项目action的代码示例: xxx/application/modules/demo/mysql_select.go

package demoimport ( "github.com/go-touch/regin/app/db" "github.com/go-touch/regin/base")type MysqlSelect struct { base.Action // 继承基类action}// 执行方法(重载方法)func (this *MysqlSelect) Exec(request *base.Request) *base.Result { result := base.JsonResult() // 查询一条数据 ret := db.Model("PlusArticle").FetchRow(func(dao *db.Dao) { dao.Where("id", 202) }) // 错误处理 if err := ret.ToError(); err != nil { result.SetData("code", 1000) result.SetData("msg", "系统出了点问题~") return result } // json输出数据库查询结果 result.SetData("data", ret.ToStringMap()) return result}

*base.Request实例(封装param、get、post方法,自动json、xml解析)

获取请求方式

GetMethod() string

获取error信息

GetError() error

获取pathinfo的路径信息. 参数key:路径名 defaultValue:默认值

Param(key string, defaultValue ...string)

获取pathinfo的路径map信息. 返回值为 base.StringMap(对应基础类型map[string]string)

ParamAll() StringMap

获取Post数据, json、xml数据也用此方法.返回值为 interface{}

Post(key string, defaultValue ...interface{}) (value interface{}, err error)

获取Post数据的map, json、xml数据也用此方法. 返回值为 base.AnyMap(对应基础类型map[string]interface{})

PostAll() (anyMap AnyMap, err error) 获取一个map[string]interface{}

获取上传文件io句柄. 返回值为 []*multipart.FileHeader

PostFile(name string) []*multipart.FileHeader

更多方法使用 request 调用

...

*base.Result实例(用于响应客户端)

type Result struct { Type string // 可选值为:String、Json、Html、 Page string // 响应页面(Type = Html时必填) Status int // 状态码 200正常状态 Msg string // 提示消息 Data AnyMap // 业务数据}// 定义RespResultvar ResultInvoker *Resultfunc init() { ResultInvoker = &Result{}}// 创建Json resultfunc (r *Result) CreateJson(status int, msg string) *Result { return &Result{ Type: "Json", Page: "", Status: status, Msg: msg, Data: AnyMap{"code": 0, "msg": "", "data": ""}, }}// 创建Html resultfunc (r *Result) CreateHtml(page string, status int, msg string) *Result { return &Result{ Type: "Html", Page: page, Status: status, Msg: msg, Data: AnyMap{}, }}

获取一个可响应json的 *base.Result 实例

base.ResultInvoker.CreateJson(status int, msg string) *Result

获取一个可响应html的 *base.Result 实例

base.ResultInvoker.CreateHtml(status int, msg string) *Result

快速获取一个可响应json的 *base.Result 实例

base.JsonResult() *Result

修改业务数据即 *base.Result 的 Data 字段

(r *Result) SetData(key string, value interface{})

获取业务数据即 *base.Result 的 Data 字段

(r *Result) GetData(key string) interface{}

*base.AnyValue值类型(用于数据转换,对于不确定类型interfa{}比较适用)

获取 *base.AnyValue. 参数value:interface{}(可传任意值)

base.Eval(value interface{}) *AnyValue

返回错误信息

(av *AnyValue) ToError() error

返回原值

(av *AnyValue) ToValue() interface{}

转成int类型

(av *AnyValue) ToInt() int

转成byte类型

(av *AnyValue) ToByte() byte

转成string类型

(av *AnyValue) ToString() string

转成bool类型

(av *AnyValue) ToBool() bool

转成map[string]string类型

(av *AnyValue) ToStringMap() map[string]string

更多方法使用 *base.AnyValue 调用

...

regin定义的数据类型 (业务中可直接使用,包名base)

// 预定义常见数据类型type DataType interface { Set(key string, value interface{}) Get(key string) *AnyValue}type AnyMap map[string]interface{} // [MapType] key is string,value is 任意类型type StringMap map[string]string // [MapType] key is string,value is string 类型type IntMap map[string]int // [MapType] key is string,value is int 类型type StringSliceMap map[string][]string // [MapType] key is string,value is string Slice 类型type GeneralMap map[string]AppAction // [MapType] key is string,value is AppAction t类型type AnySlice []interface{} // [SliceType] key is index,value为任意类型type StringMapSlice []map[string]string // [SliceType] key is index,value为(key为string,value为string)的maptype AnyMapSlice []map[string]interface{} // [SliceType] key is index,value为(key为string,value为任意类型)的map

Note: 部分值为 interface{} 的类型实现了 DataType 接口, 需要类型转换可通过Get方法获取到一个 *base.AnyValue

数据库

配置项 xxx/config/dev/database.ini

[plus_center] // 配置分组,必填; 主库master.driverName = mysql // 驱动名称master.dataSourceName = root:root@tcp(127.0.0.1:3306)/dbName?charset=utf8 // 连接参数master.maxIdleConn = 100 // 空闲连接数master.maxOpenConn = 100 // 最大连接数; 从库slave.driverName = mysqlslave.dataSourceName = root:root@tcp(127.0.0.1:3306)/dbName?charset=utf8slave.maxIdleConn = 100slave.maxOpenConn = 100

Model的示例

package mysqlimport ( "github.com/go-touch/regin/app/db")type Users struct{ Id string `field:id` Username string `field:"username"`}// 注册modelfunc init() { db.RegisterModel(&Users{}, "Users")}// 数据库标识(此方法可重构,用于切换数据库,默认master)func (this *Users) Identify() string { return "plus_center.master"}// 数据库表名(此方法可重构,用于切换数据表)func (this *Users) TableName() string { return "users"}// 自定义方法func (this *Users) Method() string { ret := db.Model("Users").FetchAll(func(dao *db.Dao) { dao.Where("id", 202) })}

(this *Users) Identify() string //设置数据库连接标识,对应数据库配置的key链关系

(this *Users) TableName() string // 设置真实数据表名,如未设置则默认结构体名称(注: AdminUser 会转成 admin_user)

使用Model查询一条记录示例:

第一种方式:row := db.Model(&Users{}).FetchRow(func(dao *db.Dao) { dao.Where("id", 1)})第二种方式:// 注册 Model, 第一个参数传入model实例化的指针, 第二个可选参数,用于起别名方便调用,不传名称默认为 mysql.Users .db.RegisterModel(&Users{}, "Users")// 使用别名获取 Dao 数据对象并使用 FetchRow 方法查询row := db.Model("Users").FetchRow(func(dao *db.Dao) { dao.Where("id", 1)})

Node: 推荐使用第二种方式,可以在初始化函数 init 批量注册model,这样在系统加载的时候仅调用一次注入容器.

db.Dao方法(举例均采用上述的第二种方式)

获取Dao数据对象.

db.Model(userModel interface{})调用示例:dao := db.Model(&Users{})或db.RegisterModel(&Users{}, "Users")dao := db.Model("Users")

设置表名.(通常无需调用,注册model时已获取表名)

(d *Dao) Table(tableName string) *Dao示例:db.Model("Users").Table("message")

设置表字段.参数field: 可为string或[]string

(d *Dao) Field(field interface{}) *Dao示例:db.Model("Users").Field("a,b,c,d")db.Model("Users").Field([]string{"a,b,c,d"})

设置查询条件. 参数field:字段名,参数value:字段值,参数linkSymbol:连接符(and[or] 默认and)

(d *Dao) Where(field interface{}, value interface{}, linkSymbol ...string) *Dao示例:db.Model("Users").Where("id", 1)

批量设置查询条件,和where类似. 参数是 key-value 的 map

(d *Dao) WhereMap(fieldMap map[string]interface{}, linkSymbol ...string) *Dao示例:db.Model("Users").WhereMap(map[string]interface{}{"id":1})

绑定数据,insert[update]时使用到.

(d *Dao) Values(valueMap map[string]interface{}) *Dao示例:db.Model("Users").Values(map[string]interface{}{"username":"zhangsan"})

设置排序. 参数不定

(d *Dao) Order(expr ...string) *Dao示例:db.Model("Users").Order("id ASC","username Desc")

批量设置排序. 与Order类似,参数为[]string

(d *Dao) OrderSlice(expr []string) *Dao示例:db.Model("Users").OrderSlice([]string{"id ASC","username Desc"})

设置查询检索记录行. 参数不定,对应sql语句 limit m,n

(d *Dao) Limit(limit ...int) *Dao示例:db.Model("Users").Limit(1,10)

是否返回sql. 需要在执行增删改查方法前调用

(d *Dao) Sql() *Dao示例:ret := db.Model("Users").FetchRow(func(dao *db.Dao) { dao.Sql()})fmt.Println(ret.ToString()) // 打印字符串sql语句

查询一条记录,返回 *db.AnyValue,可实现数据转换.参数userFunc:用户回调函数,接收参数为 *db.Dao

(d *Dao) FetchRow(userFunc ...UserFunc) *AnyValue示例:ret := db.Model("Users").FetchRow(func(dao *db.Dao) { dao.Where("id", 1)})ret.ToError() // 可获取错误信息,如果返回nil,则说明无错误发生ret.ToStringMap // 返回 map[string]string 结构的一条数据

查询多条记录,返回 *db.AnyValue,可实现数据转换. 参数userFunc:用户回调函数,接收参数为 *db.Dao

(d *Dao) FetchAll(userFunc ...UserFunc) *AnyValue示例:ret := db.Model("Users").FetchAll(func(dao *db.Dao) { dao.Where("id", 1)})ret.ToError() // 可获取错误信息,如果返回nil,则说明无错误发生ret.ToStringMap // 返回 map[string]string 结构的一条数据

插入一条记录,返回 *db.AnyValue,可实现数据转换. 参数userFunc:用户回调函数,接收参数为 *db.Dao

(d *Dao) Insert(userFunc ...UserFunc) *AnyValue示例:ret := db.Model("Users").Insert(func(dao *db.Dao) { dao.Values(map[string]interface{}{"username":"zhangsan"})})ret.ToError() // 可获取错误信息,如果返回nil,则说明无错误发生ret.ToLastInsertId() // 返回最后插入的主键id

更新一条记录,返回 *db.AnyValue,可实现数据转换. 参数userFunc:用户回调函数,接收参数为 *db.Dao

(d *Dao) Update(userFunc ...UserFunc) *AnyValue示例:ret := db.Model("Users").Update(func(dao *db.Dao) { dao.Values(map[string]interface{}{"username":"zhangsan"})})ret.ToError() // 可获取错误信息,如果返回nil,则说明无错误发生ret.ToAffectedRows() // 返回受影响行数

删除一条数据,返回 *db.AnyValue,可实现数据转换. 参数userFunc:用户回调函数,接收参数为 *db.Dao

(d *Dao) DELETE(userFunc ...UserFunc) *AnyValue示例:ret := db.Model("Users").DELETE(func(dao *db.Dao) { dao.Where("id", 1)})ret.ToError() // 可获取错误信息,如果返回nil,则说明无错误发生ret.ToAffectedRows() // 返回受影响行数

完整数据库操作实例(假设model已注册)

查询一条数据

// 链式操作ret := db.Model("Users").Field("username").Where("id", 1).FetchRow()// 匿名函数回调操作ret := db.Model("Users").FetchRow(func(dao *db.Dao) { dao.Field("username") dao.Where("id", 1)})ret.ToError()ret.ToStringMap()

查询多条数据

// 链式操作ret := db.Model("Users").Field("username").Where("id", 1).FetchAll()// 匿名函数回调操作ret := db.Model("Users").FetchAll(func(dao *db.Dao) { dao.Field("username") dao.Where("id", 1)})ret.ToError()ret.ToStringMapSlice()

插入一条数据

// 链式操作ret := db.Model("Users").Values(map[string]interface{}{"username":"zhangsan"}).Insert()// 匿名函数回调操作ret := db.Model("Users").Insert(func(dao *db.Dao) { dao.Values(map[string]interface{}{"username":"zhangsan"})})ret.ToError()ret.ToLastInsertId()

更新一条数据

// 链式操作ret := db.Model("Users").Values(map[string]interface{}{"username":"zhangsan"}).Where("id", 1).Update()// 匿名函数回调操作ret := db.Model("Users").Update(func(dao *db.Dao) { dao.Values(map[string]interface{}{"username":"zhangsan"}) dao.Where("id", 1)})ret.ToError()ret.ToAffectedRows()

删除一条数据

// 链式操作ret := db.Model("Users").Where("id", 1).DELETE()// 匿名函数回调操作ret := db.Model("Users").DELETE(func(dao *db.Dao) { dao.Where("id", 1)})ret.ToError()ret.ToAffectedRows()

Redis

配置项 xxx/config/dev/redis.ini

[plus_center] // // 配置分组,必填master.host = 127.0.0.1:6379 // 主机端口master.password = "" // 密码master.db = 10 // 库标master.MaxIdle = 16 // 空闲连接数master.MaxActive = 32 // 最大连接数 master.IdleTimeout = 120 // 超时时间

RedisModel的示例

package redistype TestModel struct {}// Redis库标识func (b *Base) Identify() string { return "plus_center.master"}

(this *Users) Identify() string // 设置redis连接参数,对应Redis配置的key链关系

Redis的使用示例:

传入一个model获取 Redis Dao 实例

RedisModel(model interface{}) *RedisDao示例:redisDao := RedisModel(&TestModel{})

获取连接池对象,开发者可通过此返回值

(rd *RedisDao) Pool() *redis.Pool示例:pool := RedisModel(&TestModel{}).Pool()

执行redis命令,返回*base.AnyValue,可进行类型转换. 参数name:命令名称 args:该命令对应的参数

(rd *RedisDao) Command(name string, args ...interface{}) *base.AnyValue示例:RedisModel(&TestModel{}).Command("SET","username","admin")RedisModel(&TestModel{}).Command("HSET","user","username","admin")ret := RedisModel(&TestModel{}).Command("GET","username")ret.ToError() // 可获取错误信息,如果返回nil,则说明无错误发生ret.ToAffectedRows() // 返回受影响行数

Utils工具

Form表单验证

Form Model结构体示例

type PlusUsers struct { UserId int `key:"user_id" require:"true" length:"0|5"` Account string `key:"account" require:"true" length:"0|20"`}

Form验证器的使用

第一种方式:result := validator.Form(&PlusUsers{}).Verify(&map[string]interface{}{ "user_id": 1,})第二种方式:validator.RegisterForm(&PlusUsers{}, "PlusUsers")result := validator.Form("PlusUsers").Verify(&map[string]interface{}{ "user_id": 1,})

Form验证器方法:

获取一个Form Dao

// 获取 Form DaoForm(userModel interface{}) *FormHandle示例:formDao := validator.Form(&PlusUsers{})

获取一个Form Dao(另一种方式)

// 注册 Form ModelRegisterForm(userModel interface{}, alias ...string)// 获取 Form DaoForm(userModel interface{}) *FormHandle示例:validator.RegisterForm(&PlusUsers{}, "PlusUsers")formDao := validator.Form("PlusUsers")

验证一个*map[string]interface{}

(mh *FormHandle) Verify(vMap *map[string]interface{}) []*tag.Result

Curl使用

GET请求

获取一个 *curl.GetCaller

func Get() *GetCaller

设置header信息

func (gc *GetCaller) Header(header map[string]string)

发送一个GET请求

func (gc *GetCaller) Call(url string, args ...map[string]interface{}) *multitype.AnyValue

GET请求示例:

get := curl.Get()// 如需设置header, 则使用此方法get.Header(map[string]string{"Authorization":"Basic MTAwMToxMjM0NTY="})// 发送请求get.Call("http://baidu.com",map[string]interface{}{ "user_id": 1, "username": "admin", "password": "123456",})

POST请求

获取一个 *curl.PostCaller

func Post() *PostCaller

设置header信息

func (pc *PostCaller) Header(header map[string]string)

发送一个POST请求

func (pc *PostCaller) Call(url string, args ...interface{}) *multitype.AnyValue

POST请求示例:

post := curl.Post()// 如需设置header, 则使用此方法post.Header(map[string]string{"Authorization":"Basic MTAwMToxMjM0NTY="})// 设置 json 请求 header, 默认 header {"Content-Type": "application/x-www-form-urlencoded"}post.Header(map[string]string{"Content-Type": "application/json"})// 发送请求(key-value形式)post.Call("http://baidu.com",map[string]interface{}{ "user_id": 1, "username": "admin", "password": "123456",})// 发送请求(json串形式)post.Call("http://baidu.com",`{"user_id":1,"username":"admin","password":"123456"}`)

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:MySQL/Oracle视图的创建与使用
下一篇:darknet深度学习框架源码分析:详细中文注释,涵盖框架原理与实现语法分析
相关文章

 发表评论

暂时没有评论,来抢沙发吧~