layouts: - path: main.go delims: - "" - "" body: |- // Code generated by hertz generator. package main import ( "context" "github.com/cloudwego/hertz/pkg/app" "github.com/cloudwego/hertz/pkg/app/middlewares/server/recovery" "github.com/cloudwego/hertz/pkg/app/server" "github.com/cloudwego/hertz/pkg/common/hlog" "github.com/cloudwego/hertz/pkg/common/utils" "github.com/cloudwego/hertz/pkg/protocol/consts" "github.com/hertz-contrib/cors" "github.com/hertz-contrib/gzip" "github.com/hertz-contrib/logger/accesslog" hertzlogrus "github.com/hertz-contrib/logger/logrus" "github.com/hertz-contrib/pprof" "{{.GoModule}}/biz/router" "{{.GoModule}}/conf" "gopkg.in/natefinch/lumberjack.v2" ) func main() { // init initialize.Init() address := conf.GetConf().Hertz.Address h := server.New(server.WithHostPorts(address)) // add a ping route to test h.GET("/ping", func(c context.Context, ctx *app.RequestContext) { ctx.JSON(consts.StatusOK, utils.H{"ping": "pong"}) }) router.GeneratedRegister(h) // do what you wanted // add some render data: registerMiddleware(h) h.Spin() } func registerMiddleware(h *server.Hertz) { // pprof if conf.GetConf().Hertz.EnablePprof { pprof.Register(h) } // gzip if conf.GetConf().Hertz.EnableGzip { h.Use(gzip.Gzip(gzip.DefaultCompression)) } // access log if conf.GetConf().Hertz.EnableAccessLog { h.Use(accesslog.New()) } // log logger := hertzlogrus.NewLogger() hlog.SetLogger(logger) hlog.SetLevel(conf.LogLevel()) hlog.SetOutput(&lumberjack.Logger{ Filename: conf.GetConf().Hertz.LogFileName, MaxSize: conf.GetConf().Hertz.LogMaxSize, MaxBackups: conf.GetConf().Hertz.LogMaxBackups, MaxAge: conf.GetConf().Hertz.LogMaxAge, }) // recovery h.Use(recovery.Recovery()) // cores h.Use(cors.Default()) } - path: go.mod delims: - '{{' - '}}' body: |- module {{.GoModule}} {{- if .UseApacheThrift}} replace github.com/apache/thrift => github.com/apache/thrift v0.13.0 {{- end}} - path: router/hertz/register.go delims: - "" - "" body: |- // Code generated by hertz generator. DO NOT EDIT. package router import ( "github.com/cloudwego/hertz/pkg/app/server" ) // GeneratedRegister registers routers generated by IDL. func GeneratedRegister(r *server.Hertz){ //INSERT_POINT: DO NOT DELETE THIS LINE! } - path: conf/conf.go delims: - "" - "" body: |- package conf import ( "fmt" "os" "gitea.micah.com/micah/standard/pkg/json" "gitea.micah.com/micah/standard/pkg/toml" "gitea.micah.com/micah/standard/pkg/yaml" ) var ( conf *Config configTypeYaml = "yaml" configTypeJson = "json" configTypeToml = "toml" configTypeMap = map[string]func(name string, obj interface{}) error{ configTypeYaml: yaml.Parse, configTypeJson: json.Parse, configTypeToml: toml.Parse, } ) type MySQL struct { LogLevel string `json:"log_level" yaml:"log_level" toml:"log_level"` DSN string `json:"dsn" yaml:"dsn" toml:"dsn"` ReplicasDSN []string `json:"replicas_dsn" yaml:"replicas_dsn" toml:"replicas_dsn"` } type Redis struct { Address string `json:"address" yaml:"address" toml:"address"` Password string `json:"password" yaml:"password" toml:"password"` } type Hertz struct { Address string `json:"address" yaml:"address" toml:"address"` EnablePprof bool `json:"enable_pprof" yaml:"enable_pprof" toml:"enable_pprof"` EnableGzip bool `json:"enable_gzip" yaml:"enable_gzip" toml:"enable_gzip"` EnableAccessLog bool `json:"enable_access_log" yaml:"enable_access_log" toml:"enable_access_log"` LogLevel string `json:"log_level" yaml:"log_level" toml:"log_level"` LogFileName string `json:"log_file_name" yaml:"log_file_name" toml:"log_file_name"` LogMaxSize int `json:"log_max_size" yaml:"log_max_size" toml:"log_max_size"` LogMaxBackups int `json:"log_max_backups" yaml:"log_max_backups" toml:"log_max_backups"` LogMaxAge int `json:"log_max_age" yaml:"log_max_age" toml:"log_max_age"` } type Config struct { Env string Hertz *Hertz `json:"hertz" yaml:"hertz" toml:"hertz"` MySQL *MySQL `json:"mysql" yaml:"mysql" toml:"mysql"` Redis *Redis `json:"redis" yaml:"redis" toml:"redis"` } func GetConf() *Config { if conf == nil { return &Config{} } return conf } func ParseConfig() error { if conf != nil { return nil } c := &Config{} for ct, fn := range configTypeMap { configPath := fmt.Sprintf("./conf/%s/conf.%s", GetEnv(), ct) if _, err := os.Stat(configPath); os.IsNotExist(err) { continue } err := fn(configPath, c) if err != nil { return err } break } conf = c return nil } func GetEnv() string { e := os.Getenv("GO_ENV") if len(e) == 0 { return "test" } return e } - path: conf/dev/conf.yaml delims: - "" - "" body: |- hertz: address: ":8080" enable_pprof: true enable_gzip: true enable_access_log: true log_level: info log_file_name: "log/hertz.log" log_max_size: 10 log_max_age: 3 log_max_backups: 50 mysql: log_level: info dsn: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8&parseTime=True&loc=Local" replicas_dsn: - "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8&parseTime=True&loc=Local" redis: address: "127.0.0.1:6379" password: "" - path: conf/online/conf.yaml delims: - "" - "" body: |- hertz: address: ":8080" enable_pprof: true enable_gzip: true enable_access_log: true log_level: info log_file_name: "log/hertz.log" log_max_size: 10 log_max_age: 3 log_max_backups: 50 mysql: log_level: info dsn: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8&parseTime=True&loc=Local" replicas_dsn: - "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8&parseTime=True&loc=Local" redis: address: "127.0.0.1:6379" password: "" - path: conf/test/conf.yaml delims: - "" - "" body: |- hertz: address: ":8080" enable_pprof: true enable_gzip: true enable_access_log: true log_level: info log_file_name: "log/hertz.log" log_max_size: 10 log_max_age: 3 log_max_backups: 50 mysql: log_level: info dsn: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8&parseTime=True&loc=Local" replicas_dsn: - "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8&parseTime=True&loc=Local" redis: address: "127.0.0.1:6379" password: "" - path: biz/dal/init.go delims: - "" - "" body: |- package dal import ( "{{.GoModule}}/biz/dal/mysql" "{{.GoModule}}/biz/dal/redis" ) func Init() { redis.Init() mysql.Init() } - path: biz/dal/mysql/init.go delims: - "" - "" body: |- package mysql import ( "{{.GoModule}}/conf" "gorm.io/driver/mysql" "gorm.io/gorm" ) var ( DB *gorm.DB err error ) func Init() { DB, err = gorm.Open(mysql.Open(conf.GetConf().MySQL.DSN), &gorm.Config{ PrepareStmt: true, SkipDefaultTransaction: true, }, ) if err != nil { panic(err) } } - path: biz/dal/redis/init.go delims: - "" - "" body: |- package redis import ( "context" "github.com/go-redis/redis/v8" "{{.GoModule}}/conf" ) var RedisClient *redis.Client func Init() { RedisClient = redis.NewClient(&redis.Options{ Addr: conf.GetConf().Redis.Address, Password: conf.GetConf().Redis.Password, }) if err := RedisClient.Ping(context.Background()).Err(); err != nil { panic(err) } } - path: docker-compose.yaml delims: - "" - "" body: |- version: '3' services: mysql: image: 'mysql:latest' ports: - 3306:3306 environment: - MYSQL_DATABASE=gorm - MYSQL_USER=gorm - MYSQL_PASSWORD=gorm - MYSQL_RANDOM_ROOT_PASSWORD="yes" redis: image: 'redis:latest' ports: - 6379:6379 - path: readme.md delims: - "" - "" body: |- # *** Project ## introduce - Use the [Hertz](https://github.com/cloudwego/hertz/) framework - Integration of pprof, cors, recovery, access_log, gzip and other extensions of Hertz. - Generating the base code for unit tests. - Provides basic profile functions. - Provides the most basic MVC code hierarchy. ## Directory structure | catalog | introduce | | ---- | ---- | | conf | Configuration files | | main.go | Startup file | | hertz_gen | Hertz generated model | | biz/handler | Used for request processing, validation and return of response. | | biz/service | The actual business logic. | | biz/dal | Logic for operating the storage layer | | biz/route | Routing and middleware registration | | biz/utils | Wrapped some common methods | ## How to run ```shell sh build.sh sh output/bootstrap.sh ``` - path: .gitignore delims: - "" - "" body: |- *.o *.a *.so _obj _test *.[568vq] [568vq].out *.cgo1.go *.cgo2.c _cgo_defun.c _cgo_gotypes.go _cgo_export.* _testmain.go *.exe *.exe~ *.test *.prof *.rar *.zip *.gz *.psd *.bmd *.cfg *.pptx *.log *nohup.out *settings.pyc *.sublime-project *.sublime-workspace !.gitkeep .DS_Store /.idea /.vscode /output *.local.yml - path: .hz delims: - "{{" - "}}" body: |- // Code generated by hz. DO NOT EDIT. hz version: {{.hzVersion}}, - path: .gitignore delims: - "" - "" body: |- *.o *.a *.so _obj _test *.[568vq] [568vq].out *.cgo1.go *.cgo2.c _cgo_defun.c _cgo_gotypes.go _cgo_export.* _testmain.go *.exe *.exe~ *.test *.prof *.rar *.zip *.gz *.psd *.bmd *.cfg *.pptx *.log *nohup.out *settings.pyc *.sublime-project *.sublime-workspace !.gitkeep .DS_Store /.idea /.vscode /output *.local.yml - path: biz/utils/resp.go delims: - "{{" - "}}" body: |- package utils import ( "context" "github.com/cloudwego/hertz/pkg/app" ) // SendErrResponse pack error response func SendErrResponse(ctx context.Context, c *app.RequestContext, code int, err error) { // todo edit custom code c.String(code, err.Error()) } // SendSuccessResponse pack success response func SendSuccessResponse(ctx context.Context, c *app.RequestContext, code int, data interface{}) { // todo edit custom code c.JSON(code, data) } - path: build.sh delims: - "{{" - "}}" body: |- #!/bin/bash RUN_NAME={{.ServiceName}} mkdir -p output/bin output/conf cp script/bootstrap.sh output 2>/dev/null chmod +x output/bootstrap.sh cp -r conf/* output/conf go build -o output/bin/${RUN_NAME} - path: script/bootstrap.sh delims: - "{{" - "}}" body: |- #!/bin/bash CURDIR=$(cd $(dirname $0); pwd) BinaryName={{.ServiceName}} echo "$CURDIR/bin/${BinaryName}" exec $CURDIR/bin/${BinaryName}