diff --git a/book/v4/README.md b/book/v4/README.md index c40be4b..d63e3ab 100644 --- a/book/v4/README.md +++ b/book/v4/README.md @@ -17,7 +17,6 @@ mcube 与 Ioc Book/Comment: 这个业务模块提供的功能 - ## 具体实现 diff --git a/book/v4/application.toml b/book/v4/application.toml index e664f4b..cb66070 100644 --- a/book/v4/application.toml +++ b/book/v4/application.toml @@ -18,3 +18,6 @@ host = "127.0.0.1" port = 8010 path_prefix = "api" + +[comment] + max_comment_per_book = 200 \ No newline at end of file diff --git a/book/v4/apps/book/README.md b/book/v4/apps/book/README.md index c44b65b..821637a 100644 --- a/book/v4/apps/book/README.md +++ b/book/v4/apps/book/README.md @@ -140,4 +140,183 @@ func (c *CommentServiceImpl) AddComment(ctx context.Context, in *comment.AddComm 2. (API)对外提供 HTTP接口, RESTful接口 3. (API)对内提供 RPC接口(JSON RPC/GRPC/thrift) +1. 开发业务功能 +```go +func (h *BookApiHandler) createBook(ctx *gin.Context) { + req := book.NewCreateBookRequest() + if err := ctx.BindJSON(req); err != nil { + response.Failed(ctx, err) + return + } + ins, err := h.svc.CreateBook(ctx.Request.Context(), req) + if err != nil { + response.Failed(ctx, err) + return + } + + // 返回响应 + response.Success(ctx, ins) +} +``` + +2. 注册路由 +```go +type BookApiHandler struct { + ioc.ObjectImpl + + // 业务依赖 + svc book.Service +} + +func (h *BookApiHandler) Name() string { + return "books" +} + +// 对象的初始化, 初始化对象的一些熟悉 &BookApiHandler{} +// 构造函数 +// 当你这个对象初始化的时候,直接把的处理函数(ApiHandler注册给Server) +func (h *BookApiHandler) Init() error { + h.svc = book.GetService() + r := ioc_gin.ObjectRouter(h) + + r.GET("", h.queryBook) + r.POST("", h.createBook) + return nil +} + +func init() { + ioc.Api().Registry(&BookApiHandler{}) +} +``` + +## 业务注册 + +每写完一个业务,就需要在 注册到ioc(注册表) +```go +// 业务加载区, 选择性的价值的业务处理对象 + +import ( + // Api Impl + _ "122.51.31.227/go-course/go18/book/v4/apps/book/api" + + // Service Impl + _ "122.51.31.227/go-course/go18/book/v4/apps/book/impl" + _ "122.51.31.227/go-course/go18/book/v4/apps/comment/impl" +) +``` + + +## 启动服务 + +```go +import ( + "github.com/infraboard/mcube/v2/ioc/server/cmd" + + // 业务对象 + _ "122.51.31.227/go-course/go18/book/v4/apps" +) + +func main() { + // ioc框架 加载对象, 注入对象, 配置对象 + // server.Gin.Run() + // application.Get().AppName + // http.Get().Host + // server.DefaultConfig.ConfigFile.Enabled = true + // server.DefaultConfig.ConfigFile.Path = "application.toml" + // server.Run(context.Background()) + // 不能指定配置文件逻辑 + // 使用者来说,体验不佳 + + // ioc 直接提供server, 直接run就行了, + // mcube 包含 一个 gin Engine + // CLI, start 指令 -f 指定配置文件 + cmd.Start() +} +``` + +```toml +[app] + name = "simple_api" + description = "app desc" + address = "localhost" + encrypt_key = "defualt app encrypt key" + +[datasource] + provider = "mysql" + host = "127.0.0.1" + port = 3306 + database = "go18" + username = "root" + password = "123456" + auto_migrate = false + debug = false + +[http] + host = "127.0.0.1" + port = 8010 + path_prefix = "api" + +[comment] + max_comment_per_book = 200 +``` + +```sh +➜ v4 git:(main) ✗ go run main.go -f application.toml start +[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached. + +[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. + - using env: export GIN_MODE=release + - using code: gin.SetMode(gin.ReleaseMode) + +2025-05-25T15:59:33+08:00 INFO config/gin/framework.go:41 > enable gin recovery component:GIN_WEBFRAMEWORK +200 +[GIN-debug] GET /api/simple_api/v1/books --> 122.51.31.227/go-course/go18/book/v4/apps/book/api.(*BookApiHandler).queryBook-fm (4 handlers) +[GIN-debug] POST /api/simple_api/v1/books --> 122.51.31.227/go-course/go18/book/v4/apps/book/api.(*BookApiHandler).createBook-fm (4 handlers) +2025-05-25T15:59:33+08:00 INFO ioc/server/server.go:74 > loaded configs: [app.v1 trace.v1 log.v1 validator.v1 gin_webframework.v1 datasource.v1 grpc.v1 http.v1] component:SERVER +2025-05-25T15:59:33+08:00 INFO ioc/server/server.go:75 > loaded controllers: [comment.v1 book.v1] component:SERVER +2025-05-25T15:59:33+08:00 INFO ioc/server/server.go:76 > loaded apis: [books.v1] component:SERVER +2025-05-25T15:59:33+08:00 INFO ioc/server/server.go:77 > loaded defaults: [] component:SERVER +2025-05-25T15:59:33+08:00 INFO config/http/http.go:144 > HTTP服务启动成功, 监听地址: 127.0.0.1:8010 component:HTTP +``` + +## 总结 + +业务分区框架, 我们专注于业务对象的开发, mcube相对于一个工具箱,承接其他非业务的公共功能 + + +## 其他非功能需求 + +工具箱 提供很多工具,开箱即用, 比如health check, 比如metrics + +```go + // 健康检查 + _ "github.com/infraboard/mcube/v2/ioc/apps/health/gin" + // metrics + _ "github.com/infraboard/mcube/v2/ioc/apps/metric/gin" +``` + + +[metric.v1 books.v1 health.v1] metric, health 使用注入的对象 +```sh +➜ v4 git:(main) ✗ go run main.go -f application.toml start +[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached. + +[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. + - using env: export GIN_MODE=release + - using code: gin.SetMode(gin.ReleaseMode) + +2025-05-25T16:06:42+08:00 INFO config/gin/framework.go:41 > enable gin recovery component:GIN_WEBFRAMEWORK +200 +[GIN-debug] GET /metrics/ --> github.com/infraboard/mcube/v2/ioc/apps/metric/gin.(*ginHandler).Registry.func1 (5 handlers) +2025-05-25T16:06:42+08:00 INFO metric/gin/metric.go:89 > Get the Metric using http://127.0.0.1:8010/metrics component:METRIC +[GIN-debug] GET /api/simple_api/v1/books --> 122.51.31.227/go-course/go18/book/v4/apps/book/api.(*BookApiHandler).queryBook-fm (5 handlers) +[GIN-debug] POST /api/simple_api/v1/books --> 122.51.31.227/go-course/go18/book/v4/apps/book/api.(*BookApiHandler).createBook-fm (5 handlers) +[GIN-debug] GET /healthz/ --> github.com/infraboard/mcube/v2/ioc/apps/health/gin.(*HealthChecker).HealthHandleFunc-fm (5 handlers) +2025-05-25T16:06:42+08:00 INFO health/gin/check.go:55 > Get the Health using http://127.0.0.1:8010/healthz component:HEALTH_CHECK +2025-05-25T16:06:42+08:00 INFO ioc/server/server.go:74 > loaded configs: [app.v1 trace.v1 log.v1 validator.v1 gin_webframework.v1 datasource.v1 grpc.v1 http.v1] component:SERVER +2025-05-25T16:06:42+08:00 INFO ioc/server/server.go:75 > loaded controllers: [comment.v1 book.v1] component:SERVER +2025-05-25T16:06:42+08:00 INFO ioc/server/server.go:76 > loaded apis: [metric.v1 books.v1 health.v1] component:SERVER +2025-05-25T16:06:42+08:00 INFO ioc/server/server.go:77 > loaded defaults: [] component:SERVER +2025-05-25T16:06:42+08:00 INFO config/http/http.go:144 > HTTP服务启动成功, 监听地址: 127.0.0.1:8010 component:HTTP +``` \ No newline at end of file diff --git a/book/v4/apps/comment/impl/impl.go b/book/v4/apps/comment/impl/impl.go index d23dd78..934db33 100644 --- a/book/v4/apps/comment/impl/impl.go +++ b/book/v4/apps/comment/impl/impl.go @@ -1,9 +1,18 @@ package impl import ( + "fmt" + "122.51.31.227/go-course/go18/book/v4/apps/comment" + "github.com/infraboard/mcube/v2/ioc" ) +func init() { + ioc.Controller().Registry(&CommentServiceImpl{ + MaxCommentPerBook: 100, + }) +} + // 怎么知道他有没有实现该业务, 可以通过类型约束 // var _ book.Service = &BookServiceImpl{} @@ -15,4 +24,18 @@ var _ comment.Service = (*CommentServiceImpl)(nil) // Book业务的具体实现 type CommentServiceImpl struct { + ioc.ObjectImpl + + // Comment最大限制 + MaxCommentPerBook int `toml:"max_comment_per_book"` +} + +func (s *CommentServiceImpl) Init() error { + // 当前对象,已经读取了配置文件 + fmt.Println(s.MaxCommentPerBook) + return nil +} + +func (s *CommentServiceImpl) Name() string { + return comment.APP_NAME } diff --git a/book/v4/main.go b/book/v4/main.go index 293945a..34f1da7 100644 --- a/book/v4/main.go +++ b/book/v4/main.go @@ -5,6 +5,11 @@ import ( // 业务对象 _ "122.51.31.227/go-course/go18/book/v4/apps" + + // 健康检查 + _ "github.com/infraboard/mcube/v2/ioc/apps/health/gin" + // metrics + _ "github.com/infraboard/mcube/v2/ioc/apps/metric/gin" ) func main() { diff --git a/go.mod b/go.mod index fee9d9d..fb629ec 100644 --- a/go.mod +++ b/go.mod @@ -15,9 +15,11 @@ require ( require ( github.com/BurntSushi/toml v1.5.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect github.com/bytedance/sonic v1.13.2 // indirect github.com/bytedance/sonic/loader v0.2.4 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cloudwego/base64x v0.1.5 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect @@ -55,9 +57,14 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_golang v1.22.0 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.63.0 // indirect + github.com/prometheus/procfs v0.16.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/spf13/cobra v1.9.1 // indirect github.com/spf13/pflag v1.0.6 // indirect diff --git a/go.sum b/go.sum index 9be0048..c2c67b2 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ= github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= @@ -9,6 +11,8 @@ github.com/caarlos0/env/v6 v6.10.1 h1:t1mPSxNpei6M5yAeu1qtRdPAK29Nbcf/n3G7x+b3/I github.com/caarlos0/env/v6 v6.10.1/go.mod h1:hvp/ryKXKipEkcuYjs9mI4bBCg+UI0Yhgm5Zu0ddvwc= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= @@ -87,6 +91,8 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= @@ -95,6 +101,8 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= @@ -112,12 +120,22 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= +github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k= +github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18= +github.com/prometheus/procfs v0.16.0 h1:xh6oHhKwnOJKMYiYBDWmkHqQPyiY40sny36Cmx2bbsM= +github.com/prometheus/procfs v0.16.0/go.mod h1:8veyXUu3nGP7oaCxhX6yeaM5u4stL2FeMXnCqhDthZg= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=