Introducing Socket Firewall: Free, Proactive Protection for Your Software Supply Chain.Learn More
Socket
Book a DemoInstallSign in
Socket

github.com/duanchi/min

Package Overview
Dependencies
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

github.com/duanchi/min

Source
Go
Version
v1.9.1
Version published
Created
Source

Min-Go

项目初始化

min-go 支持go mod初始化

require (
	github.com/duanchi/min v1.6.14
)

配置文件

配置结构体

项目中所有的配置可以通过定义一个struct类型的变量, 并由config/application.yaml填充配置项内容, 该变量可以引用github.com/duanchi/min/types下的Config结构体进行组合。

package config

import "github.com/duanchi/min/types"

var Config = struct {
	types.Config	`yaml:",inline"`

	Jwt struct {
		SignatureKey string `yaml:"jwt_signature_key" default:"${JWT_SIGNATURE_KEY}"`
		ExpiresIn  int64 `yaml:"jwt_expires_in" default:"${JWT_EXPIRES_IN:7200}"`
	} // 自定义配置

	Beans struct {} // IOC容器初始化
}{}

在配置结构体中, 需要定义yaml的标签指明扩展配置文件的对应位置, 也可以通过default标签来指定配置的默认值

配置文件、默认值中可以使用${}的方式指定对应的环境变量, 也可以使用${ENV_KEY:default_value}的方式指定当未找到该环境变量时赋予的默认值

配置字段中的实际赋值可根据字段基本类型自动进行类型转换, 支持的基本类型有int/int64 float64 string bool

配置yaml文件默认配置在config/application.yaml, 可以通过Bootstrap方法更改配置文件位置

env: "${ENV:development}"
#服务配置
application:
  server_port: "${SERVER_PORT:9801}"
  jwt_signature_key: "${JWT_SIGNATURE_KEY}"
  jwt_expire_in: "${JWT_EXPIRE_IN:7200}"
db:
  enabled: true
  dsn: "${DB_DSN:postgres://postgres:shvEVodOcqqTCWJ0@61.55.158.34:58932/cloud?sslmode=disable&prefix=dp_}"
func main() {
	heron.SetConfigFile("./config/dashboard.yaml")
	heron.Bootstrap(&Config)
	return
}

获取配置值

在项目初始化后,可以直接引入该变量读取初始化后的配置。也可以通过配置获取方法config.Get获取配置

直接获取配置

import xxx/config
Dsn := Config.Db.Dsn
// host=172.31.16.1 port=3308 user=tb_cloud password=123456 dbname=thingsboard sslmode=disable

推荐使用配置变量直接获取配置, 既可以准确定位配置元素, 又可以省去类型强制转换。

通过Get方法获取配置

package config

func Get(key string) interface{} {}

其中key是以.分割的配置定义层级,获取配置后,需要进行强制类型转换。

import "heurd.com/config"

func getConfig () {
    fmt.Println(config.Get("Db.Enabled").(bool))
    fmt.Println(config.Get("Db.Dsn").(string))
}

// true
// host=172.31.16.1 port=3308 user=tb_cloud password=123456 dbname=thingsboard sslmode=disable

读取配置后, 需手动进行类型转换

在Bean中注入配置值

在Bean(可参考IOC容器章节)中, 可以使用value标签以类似配置文件中获取环境变量的方式获取配置值

struct Sample struct {
  Expires string `value:"${Jwt.Expires}"`
}

为保证值可以正确注入, 需要将被注入的属性或字段设置为可导出

项目文件结构

建议采用三层分离的文件结构,即控制器业务逻辑服务实体关系映射三层,分别对应controllersevicemapper三个包。

root

  • main.go
  • config.go
  • controller
    • xxx.go 控制器文件
  • service
    • xxx.go 业务逻辑文件
  • mapper
    • xxx.go 数据库mapper文件

IOC容器

借鉴于Java SpringIOC容器概念,可以通过定义Bean进行项目中实体实例的管理,在初始化后可在任何位置调用。

Bean定义

使用类似配置文件定义时使用的自定义结构体进行Bean的定义,字段名为Beanname, 字段类型为Bean实例的类型, 可通过标签配置扩展Bean配置信息

package config

var Beans = struct {
	DataDevices controller.DevicesController `route:"data/devices"`
  [bean name] [bean struct] `[bean tags]`
}{}

若需实现上述Bean的IOC/DI,需继承min.abstract.Bean类型,并实现 Init方法

min.abstract.Bean已经实现了空的Init方法,若初始化时不需任何额外操作,可不进行方法重写。

预定义的抽象基础类min.abstract.RestControllermin.abstract.Service已经继承了min.abstract.Bean类型,可以直接使用并在Bean定义文件中引用

type Devices struct {
	abstract.Service
	Config string `value:"${Db.Dsn,172.31.128.5}"`
	Data *data.Devices `autowired:"true"`
}

func (service *Devices) Init() {
	fmt.Println("Inited!") // 初始化时将打印 'Inited!'
}

Bean初始化

Bean定义完成后, 通过加入到Config文件的 Beans结构中, 可以实现Bean的自动初始化

var Config = struct {
	types.Config	`yaml:",inline"`
  // ...
	Beans struct {

		GatewayMiddleware middleware.GatewayMiddleware `middleware:"true"`

		AuthorizationToken authorization.TokenController `rest:"authorization/token"`

		AccountService authorization2.AccountService
		TokenService authorization2.TokenService
	}
}{}

Bean初始化切面

可通过实现Bean类型的Init方法实现Bean初始化后的操作

[bean name]

用于标识当前Beanname,可在min.GetBean方法参数中使用

[bean struct]

用于当前Bean类型或类的初始化,初始化后,将生成一个当前类型的实例

[bean tags]

用于描述当前Bean的特定属性,可在初始化后进行扩展操作

bean tag的可取值如下

value

用于设置当前属性或字段的值,可以使用${[config-stack]}来进行配置文件的读取,读取的值将自动转换为当前字段的类型,支持的类型有intint64float64stringboolstruct

autowired

用于在Bean初始化后,将含有当前字段类型的Bean自动装载至当前的字段中,装载时将装载对象的引用类型。

自动装载时,字段类型需设置为将要装载类型Bean的指针类型,并将autowired值设置为true

routerestmethod

详见Http服务章节中的路由配置

middleware

用于定义基于HTTP服务的中间件处理方法, 如定义一个登录或者令牌授权认证、请求日志记录等, 通过继承abstract.middlewire定义一个中间件处理方法

type AuthorizationMiddleware struct {
	abstract.Middleware
	TokenService *service.TokenService `autowired:"true"`
}

func (this *AuthorizationMiddleware) AfterRoute (ctx *gin.Context) {
  // 具体处理方法
	ctx.Next()
	return
}
扩展取值

提供可自定义的tag标签,并通过扩展方法执行Bean初始化时的扩展操作。

可通过继承types.BeanParser来实现一个自定义的Bean处理扩展, 类似Java Spring中的注解定义

type NativeApiBeanParser struct {
	types.BeanParser
}

func (parser NativeApiBeanParser) Parse (tag reflect.StructTag, bean reflect.Value, definition reflect.Type, beanName string) {
	resource := tag.Get("native_api")

	if resource != "" {
		NativeApiBeans[resource] = bean
	}
}

在Config结构体中加入配置

var Config = struct {
	config.Config	`yaml:",inline"`
	// ...
	Beans struct {
		NativeApiRoutesController native_api.RoutesController `native_api:"routes"`
		NativeApiServicesController native_api.ServicesController `native_api:"services"`
	}
}{
	Config: config.Config{
		Config: types.Config{
			BeanParsers: []_interface.BeanParserInterface{
				&native_api.NativeApiBeanParser{},
			},
		},
	},
}

项目初始化后可通过min.GetBean方法获取Bean

import min

func Test() {
  min.GetBean("Fetch").(Fetch).Get()
}

只有在Config中定义的Bean才可以使用Bean的各种特性, 如自动初始化、全局对象、自动注入等特性

Http服务

项目初始化后,可以使用min.HttpServer进行Http服务器的相关操作

服务器端口配置可以使用配置ServerPort 指定

Http服务器使用Gin

路由配置

请求路由目前可根据资源进行路由配置,是通过扩展Bean定义实现的,因此只需在Bean变量中添加名为routerestrestful的标签, 并设置其属性值为绑定路径或资源路径即可,Bean字段类型为相应的处理结构体。

另外还可以追加使用method方法限定该路由处理方法可以处理的HTTP请求类型, 多个类型以,分割

rest路由配置完成后,可自动配置[resource], [resource]/:id[resource]/的路由解析

Restful控制器

创建Restful控制器只需新建一个结构体,组合abstract.RestController,并实现当前控制器关心的处理方法即可。

若不组合abstract.RestController,则需实现所有min.interface.RestControllerInterface方法

可实现的方法有

Fetch(获取) - GET

func (controller RestController)
Fetch (
    id string,
    resource string,
    parameters *gin.Params,
    ctx *gin.Context
) (result interface{}, err types.Error) {}

Create(创建) - POST

func (controller RestController)
Create (
    id string,
    resource string,
    parameters *gin.Params,
    ctx *gin.Context
) (result interface{}, err types.Error) {}

Update(更新) - PUT

func (controller RestController)
Update (
    id string,
    resource string,
    parameters *gin.Params,
    ctx *gin.Context
) (result interface{}, err types.Error) {}

Remove(删除) - DELETE

func (controller RestController)
Remove (
    id string,
    resource string,
    parameters *gin.Params,
    ctx *gin.Context
) (result interface{}, err types.Error) {}

Communicate(通信-基于websocket) - WEBSOCKET

func (controller RestController)
Communicate (
    connection *websocket.Conn,
  	id string, resource string,
  	parameters *gin.Params,
  	ctx *gin.Context
) (err types.Error) {}

方法返回值可以是任意可转换为json的数据格式

其余方法未完成

数据库

若设置配置 Db.Enabled=true,则可开始数据库支持。在项目中可以使用min.Db进行和数据库有关的操作。

数据库使用xorm

异常

人为抛出异常时,建议使用min.types.Error类型,并通过MessageCode字段定义异常

Code需使用HTTP协议支持的错误码。

运行

main.go 必须包含以下结构

min.Bootstrap(&Config, &Beans)

其中, Config为实际定义配置的变量,Beans为实际定义Bean的变量。项目初始化完成后,可通过引用调用配置和Bean的实际值。

项目开发环境可以使用 fresh 等hot-reload热加载方案。

FAQs

Package last updated on 13 Dec 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts