ioc

package module
v0.0.0-...-5ba8ac2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 15, 2024 License: Apache-2.0 Imports: 9 Imported by: 33

README

infra

  1. DDD 模型 Ioc 微服务开发框架
  2. 内置 Gin、Restful 框架,以及添加了 health、Cors、Swagger、Metric、Trace、Kafka、Redis... 等开箱即用的工具支持
  3. 提供默认配置,用户可以自定义配置来进行覆盖,框架会自动加载用户自定义配置
  4. 提供自动感知web 框架功能,即注册了Gin 的视图就使用Gin 框架、注册了Restful 框架就使用 Restful 框架
框架原理
Ioc 优先级说明
  • Ioc 框架设置了默认4个名称空间

    • Config namespace:存放基础的框架配置对象、以及其他对象的依赖对象,比如gin、restful、gorm、application
    • Default namespace:存放用户自定义对象,拥有较高的优先级,在Controller Namespace 之前被初始化
    • Controller Namespace:控制器对象,负责具体业务逻辑处理
    • Apis Namespace:接口对象,负责对外提供API 接口
  • Ioc 优先级示意图:

Ioc 默认配置解析
  1. Application:用于定义当前微服务描述信息
application:
  appName: "svc01"
  description: "my service"
  domain: "example.com"
  1. Cors:跨域配置
cors:
  allowedHeaders: [ "*" ]
  allowedDomains: [ ".*" ]    # for gorestful
  allowOrigins: [ "*" ]        # for gin
  allowedMethods: [ "*" ]
  exposeHeaders: [ "*" ]
  allowCookies: true
  maxAge: 43200
  1. Datasrouce: 数据库配置
datasource:
  otlp: false
  host: "127.0.0.1"
  port: 3306
  database: "must_set"
  username: "root"
  password: "redhat"
  debug: true
  1. Http:http 服务配置
http:
  host: "127.0.0.1"
  port: 8080
  readHeaderTimeout: 30
  readTimeout: 60
  writeTimeout: 60
  idleTimeout: 300
  maxHeaderSize: "16kb"
  trace: false
  ginMode: "debug"
  1. Grpc:grpc 服务配置
grpc:
  host: "127.0.0.1"
  port: 18081
  token: "my_grpc_server_token"
  1. Log:日志配置
log:
  trace: true
  callerDeep: 3
  level: debug
  filename: "logs/app.log"
  maxSize: 10
  maxAge: 30
  maxBackups: 6
  LocalTime: true
  compress: false
  deep: 3
  1. Otlp:遥测配置
otlp:
  httpEndpoint: "127.0.0.1:4318"
  grpcEndpoint: "127.0.0.1:4317"
  enableTLS: false
单元测试
在Ioc 中进行单元测试
  1. 示例
import (
    _ "case04/apps"  // 导入 apps/registry.go 中注册的所有模块
    "case04/apps/user"
    "context"
    "github.com/qiaogy91/ioc"
    "testing"
)

var (
    ctx = context.Background()
    c   = user.GetSvc()  // 通过Ioc 获取controller 
)

func init() {
    // 初始化Ioc 框架
    if err := ioc.ConfigIocObject("/Users/qiaogy/GolandProjects/projects/skill/case04/etc/application.yaml"); err != nil {
        panic(err)
    }
}
// 测试用例
func TestFn1(t *testing.T) {}
内建工具
IP地址解析
ip2region:
  filePath: "etc/ip2region.xdb"
package main

import (
  "fmt"
  "github.com/qiaogy91/ioc/default/ip2region"
)

func main() {
  c := ip2region.Get()
  res, _ := c.SearchByStr("1.2.3.4")
  fmt.Println(res)
}
内建应用
Health 检测接入
package main

import (
  _ "github.com/qiaogy91/ioc/apps/health/restful" // restful 框架的健康探测服务
  _ "github.com/qiaogy91/ioc/apps/health/gin" // gin 框架的健康探测服务,二选一
)
go run main.go start -t file
# 2024-10-04T14:06:19+08:00 INFO   gin/api.go:28             > Get the Health using http://127.0.0.1:8080/health component:HEALTH
Gin Swagger 文档
package api

// @Summary 修改文章标签
// @Description  修改文章标签
// @Tags         文章管理
// @Produce  json
// @Param id path int true "ID"
// @Param name query string true "ID"
// @Param state query int false "State"
// @Param modified_by query string true "ModifiedBy"
// @Success 200 {string} json "{"code":200,"data":{},"msg":"ok"}"
// @Router /restful/v1/tags/{id} [put]
func (h *Handler) ginCreatTable(ctx *gin.Context) {
  if err := h.svc.CreatTable(ctx); err != nil {
  ctx.JSON(http.StatusBadRequest, err)
  return
  }
  ctx.JSON(200, "ok")
}
cd ProjectRoot/
swag init
package main

import (
  _ "github.com/qiaogy91/example/docs"         // gin doc,上一步中生成的文档在项目根路径下 docs
  _ "github.com/qiaogy91/ioc/apps/health/gin"  // gin health
  _ "github.com/qiaogy91/ioc/apps/swagger/gin" // gin swagger
  _ "github.com/qiaogy91/ioc/config/cors/gin"  // gin cors
)
go run main.go -t file
# 2024-10-04T14:06:38+08:00 INFO   gin/api.go:32             > Get the API doc using http://127.0.0.1:8080/swagger/doc.json component:SWAGGER
Restful Swagger 文档
package api

func (h *Handler) Init() {
  h.svc = app01.GetSvc()
  h.log = log.Sub(app01.AppName)

  // Restful 框架路由注册
  ws := gorestful.ModuleWebservice(h)
  ws.Route(ws.GET("").To(h.restfulList).Doc("用户列表"))
  ws.Route(ws.POST("").To(h.restfulCreate).Doc("创建用户"))
  ws.Route(ws.POST("/table").To(h.restfulCreateTable).Doc("创建表结构"))
  // 打印所有已注册的路由
  for _, ws := range restful.RegisteredWebServices() {
      for _, r := range ws.Routes() {
          h.log.Info().Msgf("%-6s %s", r.Method, r.Path)
      }
  }
}
package main

import (
  _ "github.com/qiaogy91/infra/ioc/apps/swagger/restful"
  _ "github.com/qiaogy91/infra/ioc/config/cors/restful"
  _ "github.com/qiaogy91/infra/ioc/apps/health/restful"
)
go run main.go -t file 
# 2024-10-04T14:06:19+08:00 INFO   gin/api.go:32             > Get the API doc using http://127.0.0.1:8080/swagger/doc.json component:SWAGGER
Metric 指标接入
  1. 导入Ioc 模块
package main

import (
_ "github.com/qiaogy91/ioc/apps/metrics/gin" // gin metric
_ "github.com/qiaogy91/ioc/apps/metrics/restful" // restful metric,二选一
)
go run main.go start -t file 
# 2024-10-04T19:51:07+08:00 INFO   gin/api.go:47             > Get the Metric using http://127.0.0.1:8080/metrics component:METRICS
# HELP http_request_duration_histogram Histogram of the duration of HTTP requests
# TYPE http_request_duration_histogram histogram
http_request_duration_histogram_bucket{method="GET",path="/app01/",le="1"} 0
http_request_duration_histogram_bucket{method="GET",path="/app01/",le="2"} 1
http_request_duration_histogram_bucket{method="GET",path="/app01/",le="3"} 1
http_request_duration_histogram_bucket{method="GET",path="/app01/",le="4"} 3
http_request_duration_histogram_bucket{method="GET",path="/app01/",le="5"} 4
http_request_duration_histogram_bucket{method="GET",path="/app01/",le="6"} 4
http_request_duration_histogram_bucket{method="GET",path="/app01/",le="7"} 4
http_request_duration_histogram_bucket{method="GET",path="/app01/",le="+Inf"} 4
Trace 指标接入
import _ "github.com/qiaogy91/ioc/config/otlp" // 开启遥测功能
go run main.go start -t file
2024-10-04T23:51:12+08:00 INFO   server/server.go:56       > loaded configs: [app log trace gin-framework datasource cors grpc http] component:APPLICATION-SERVER
2024-10-04T23:51:12+08:00 INFO   gin/framework.go:44       > gin trace enabled component:GIN-FRAMEWORK
2024-10-04T23:51:12+08:00 INFO   datasource/mysql.go:69    > mysql trace enabled component:DATASOURCE

Documentation

Index

Constants

View Source
const (
	ConfigNamespace     = "configs"
	ControllerNamespace = "controllers"
	DefaultNamespace    = "default"
	ApiNamespace        = "apis"
)

Variables

This section is empty.

Functions

func ConfigIocObject

func ConfigIocObject(confPath string) error

ConfigIocObject 为容器中的对象进行二次配置

func OtlpMustEnabled

func OtlpMustEnabled()

Types

type Container

type Container []*Namespace

Container 容器

func GetContainer

func GetContainer() *Container

GetContainer 获取整个Ioc 容器

func (*Container) Close

func (c *Container) Close(ctx context.Context) error

func (*Container) Init

func (c *Container) Init()

func (*Container) Len

func (c *Container) Len() int

func (*Container) Less

func (c *Container) Less(i, j int) bool

func (*Container) LoadConfig

func (c *Container) LoadConfig(filePath string)

func (*Container) Namespace

func (c *Container) Namespace(ns string) *Namespace

func (*Container) Swap

func (c *Container) Swap(i, j int)

type Namespace

type Namespace struct {
	NsName   string
	Priority int
	Items    []ObjectInterface
}

Namespace 容器接口实现

func Api

func Api() *Namespace

func Config

func Config() *Namespace

func Controller

func Controller() *Namespace

func Default

func Default() *Namespace

func (*Namespace) Close

func (s *Namespace) Close(ctx context.Context) error

func (*Namespace) Get

func (s *Namespace) Get(name string) ObjectInterface

func (*Namespace) Init

func (s *Namespace) Init()

func (*Namespace) Len

func (s *Namespace) Len() int

func (*Namespace) Less

func (s *Namespace) Less(i, j int) bool

func (*Namespace) List

func (s *Namespace) List() []string

func (*Namespace) Name

func (s *Namespace) Name() string

func (*Namespace) Registry

func (s *Namespace) Registry(o ObjectInterface)

func (*Namespace) Swap

func (s *Namespace) Swap(i, j int)

type NamespaceInterface

type NamespaceInterface interface {
	Registry(obj ObjectInterface)    // 注册对象
	Get(name string) ObjectInterface // 获取对象
	List() []string                  // 打印对象名称列表
	LoadFromFile(filename string)    // 从配置文件中加载
}

NamespaceInterface 容器接口约束

type ObjectImpl

type ObjectImpl struct{}

func (*ObjectImpl) Close

func (o *ObjectImpl) Close(ctx context.Context) error

func (*ObjectImpl) Init

func (o *ObjectImpl) Init()

func (*ObjectImpl) Meta

func (o *ObjectImpl) Meta() ObjectMeta

func (*ObjectImpl) Name

func (o *ObjectImpl) Name() string

func (*ObjectImpl) Priority

func (o *ObjectImpl) Priority() int

type ObjectInterface

type ObjectInterface interface {
	Name() string                    // 对象名称
	Priority() int                   // 对象优先级
	Init()                           // 初始化对象
	Close(ctx context.Context) error // 关闭对象
	Meta() ObjectMeta                // 对象元数据描述信息,扩展使用
}

ObjectInterface 对象接口约束

type ObjectMeta

type ObjectMeta struct {
	PathPrefix string
	Extra      map[string]string
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL