Save time and energy, and create a stable and reliable web project more efficiently: a complete web project skeleton based on Go language and Gin framework. No need to start from scratch, use this skeleton to quickly build a fully functional and excellent performance Web application. Give full play to the advantages of the Go language and Gin framework to easily handle high-concurrency and large-traffic requests. Build a code architecture that is highly scalable and easy to maintain to ensure the long-term and stable operation of the project. At the same time, by integrating common functional modules and best practices, you can reduce tedious development work and focus on the implementation of business logic.
The skeleton can be used separately between each component, loosely coupled between components, and high cohesion, and the implementation of the component is based on the packaging of other three-party dependencies.
Currently this skeleton implements most components, such asevent
,middleware
,log
,Configuration
,Parameter verification
,Command line
,Timing tasks
Functions such as this can meet most development needs at present, and update functions will be continuously maintained in the future.
github address: /czx-lab/skeleton
Set environment variables and download project dependencies
go env -w GO111MODULE=on go env -w GOPROXY=,direct go mod download
Run the project
go run ./cmd/
Project compilation, packaging and running
go build ./cmd/ // Compilemake build // Runmake run // Compile and runmake // Run the project./main
Project directory structure description
├─app │ ├─command ---> Command line │ ├─controller │ │ └─ ---> BaseController,Mainly definedrequestParameter Verifiervalidator │ ├─event │ │ ├─entity ---> Event Entity Directory │ │ ├─listen ---> Event listening execution script directory │ │ └─ ---> Event registration code │ │ │ ├─middleware ---> Middleware code directory │ ├─request ---> Request parameter verification code directory │ │ └─ ---> Parameter Verifier │ └─task ---> Timed task code directory │ └─ ---> Register a timed task script ├─cmd ---> Project entrance directory │ └─cli ---> 项目Command line模式入口目录 ├─config │ └─ ---> Configuration File ├─internal ---> Encapsulation containing third-party packages ├─router ---> Routing Directory │ └─ ├─storage ---> log、Resource storage directory │ └─logs └─test ---> Unit Test Directory
Basic functions
routing
The web framework of this skeleton is gin, so the routing definition can directly read the documentation of the Gin framework.
Defining the registration route in this skeleton requiresrouter
Under the folderIn the file
func (*AppRouter) Add(server *)
Method definition registration:
("/foo", func(ctx *) { (, "hello word!") })
You can also register by defining the route yourself, just implementing it/czx-lab/skeleton/internal/server/router
The followingInterface
interface. The following example:
Define aCustomRouter
Structure, this structure implementsInterface
interface
package router import ( "net/http" "skeleton/internal/server" "/gin-gonic/gin" ) type CustomRouter struct { server } func NewCustom(srv ) *CustomRouter { return &CustomRouter{ srv, } } func (*CustomRouter) Add(srv *) { ("/custom", func(ctx *) { (, "custom router") }) }
It should be noted that if it is a custom routing registration, the project needs to be modified.
cmd
Under the folderEntry file, via
((http))
Register togin
middleware
Define middleware andgin
Like the framework, this estimate implements the middleware for panic exceptions by default, you can view itinternal/server/middleware
In the folderdocument.
If you need to define other middleware and load registration, you can use the defined middleware to passInterface
SetMiddleware(middlewares ...)
Method registration loading,
For example, we implement the following custom global middlewaremiddleware/
:
type Custom struct{} func (c *Custom) Handle() { return func(ctx *) { ("Custom middleware exec...") } }
Then use it where the route is defined(&{})
Register middleware.
Defining global routing middleware can refer torouter/
In-houseNew
method.
If it is a local middleware, you can directly register it on the specific route. Refer to the usage of gin routing middleware
log
The logs in this skeleton are direct/zap
Encapsulation, when used, directly passes global variablesAccess to the write logs, you can directly use all methods supported by zap.
package demo import "skeleton/internal/variable" func Demo() { ("info message") }
The log file defaults tojson
Format write tostorage/logs/
in
Configuration
The configuration item definition is directly inconfig/
The file is defined and configured to read and write is encapsulated/spf13/viper
Implementation, in this skeleton, only the following methods for obtaining configuration are provided:
type ConfigInterface interface { Get(key string) any GetString(key string) string GetBool(key string) bool GetInt(key string) int GetInt32(key string) int32 GetInt64(key string) int64 GetFloat64(key string) float64 GetDuration(key string) GetStringSlice(key string) []string }
It should be noted that the acquisition of configuration items is cached in the skeleton. The first load is to obtain it in the file, and every time I go back, it iscache
Get it nowcache
Only supported by defaultmemory
, customization is also supported in the skeletoncache
The method only needs to be implementedThe interface is fine, for example, if you need to use it
redis
As a configuration cache, it can be handled in the following ways:
type ConfigRedisCache struct {} var _ = (*ConfigRedisCache)(nil) func (c *ConfigRedisCache) Get(key string) any { return nil } func (c *ConfigRedisCache) Set(key string, value any) bool { return true } func (c *ConfigRedisCache) Has(key string) bool { return true } func (c *ConfigRedisCache) FuzzyDelete(key string) { }
ThenConfigRedisCache
Structure configuration toIn, as shown below, modify
internal/bootstrap/
Methods to initialize configuration:
, err := ((), { BasePath: './', Cache: &ConfigRedisCache{} })
The basic configuration is as follows:
# http configurationHttpServer: Port: ":8888" # The service mode, the value of gin is the same Mode: "debug" # socket configurationWebsocket: WriteReadBufferSize: 2048 HeartbeatFailMaxTimes: 4 PingPeriod: 20 ReadDeadline: 100 WriteDeadline: 35 PingMsg: "ping" # Database configurationDatabase: # You can view GORM-related configuration options Mysql: SlowThreshold: 5 LogLevel: 4 ConnMaxLifetime: 1 MaxIdleConn: 2 MaxOpenConn: 2 ConnMaxIdleTime: 12 Reade: - "root:root@tcp(192.168.1.4:3306)/test?charset=utf8mb4&loc=Local&parseTime=True" Write: "root:root@tcp(192.168.1.4:3306)/test?charset=utf8mb4&loc=Local&parseTime=True" #Basic configuration of mongo database Mongo: Enable: false Uri: MinPoolSize: 10 MaxPoolSize: 20 Redis: Disabled: false Addr: "192.168.1.4:6379" Pwd: "" Db: 0 PoolSize: 20 MaxIdleConn: 30 MinIdleConn: 10 # Unit (seconds) MaxLifeTime: 60 # Unit (points) MaxIdleTime: 30 # Timing tasksCrontab: Enable: true # Message queue, use rocketmqMQ: Enable: false Servers: - "127.0.0.1:9876" ConsumptionSize: 1 Retries: 1
Event mechanism
-
Define event entities
exist
app/event/entity
Define an event entity in the directory, which implementsinterface:
package entity type DemoEvent struct {} func (d *DemoEvent) EventName() string { return "demo-event" } func (d *DemoEvent) GetData() any { return "demo param" }
-
Define event listening
exist
app/event/listen
Define a directoryDemoEventListen
Event listening, andDemoEventListen
The structure must be implementedinterface:
package listen import ( "fmt" event2 "skeleton/app/event/entity" "skeleton/internal/event" ) type DemoEventListen struct { } func (*DemoEventListen) Listen() { return &{} } func (*DemoEventListen) Process(data any) (any, error) { return ("%v --> %s", data, "exec "), nil }
-
Finally, the event needs to be registered,
app/event/
In the fileInit
Execute within the method:(&{})
-
Call event execution
(&{})
Verifier
The gin framework itself is built-invalidator
Verification, the skeleton only provides a unified verification entry for the verification of its parameters.
The parameters are checked by the following methods and set the Chinese error prompt:
type Param struct { Name int `binding:"required" form:"name" query:"name" json:"name"` } appRequest, err := ("zh") if err != nil { return } var data Param errMap := (ctx, &data) (errMap)
The default parameter verification has been implemented in the skeleton, and it can beapp/request/
View in the file. And incontroller
In the directoryThere is one
Validate(ctx *, param any)
Method, when you want to perform parameter verification in other controllers, you only need to inherit.base
Structure, then callValidate
method.
package controller import "/gin-gonic/gin" type DemoController struct { base } type DemoRequest struct { Id int `binding:"required" form:"id" query:"id" json:"id"` } func (d *DemoController) Index(ctx *) { var param DemoRequest if err := (ctx, ¶m); err == nil { (, {"data": param}) } else { (, {"message": err}) } }
Verification specification reference
/go-playground/validator
Official Documentation
Command line
based on/spf13/cobra
Package
-
Define commands
exist
app/command
Define your own command in the directory, such as customizing an outputsuccess ok
Commandpackage command import ( "fmt" "/spf13/cobra" ) type FooCommand struct {} func (f *FooCommand) Command() * { return &{ Use: "foo", Short: "Introduction to Command Usage.", Long: `Command introduction.`, Run: func(cmd *, args []string) { str, _ := ().GetString("name") ("success, %s", str) }, } } func (f *FooCommand) Flags(root *) { ().String("name", "", "Command parameters") }
-
Registration command
Need to be in
cmd/cli/
In-housemain
Register custom commands within the method. -
Execute the command
go run cmd/cli/ foo --name ok
-
View command information
go run cmd/cli/ help // orgo run cmd/cli/ foo --help
Timing tasks
Timing is through packaging/robfig/cron/v3
accomplish
-
Define timing task methods
exist
app/task
Define execution methods in the directory, such as printing every minutesuccess
characterpackage task import "fmt" type SuccessTask struct { } // Time rulesfunc (s *SuccessTask) Rule() string { return "* * * * *" } func (s *SuccessTask) Execute() func() { return func() { ("success") } }
-
Loading timing tasks
Need to be in
app/task/
In the fileTasks
In the method, load custom tasks, refer to the task directorydocument
The Go language and Gin framework are ideal for developing high-performance web projects. Go is known for its simplicity, efficiency and concurrency, enabling developers to write reliable and high-performance code. The Gin framework is a lightweight web framework with fast routing capabilities and rich middleware support, allowing developers to quickly build flexible and scalable web applications. Using the Go language and Gin framework, developers can enjoy efficient development processes and excellent performance. Whether building small projects or large applications, the Go language and Gin framework provide developers with powerful tools and optimized performance, making the development process more efficient and enjoyable.
This is the article about accelerating development: a powerful tool for building web projects using Go and Gin frameworks. For more related web project skeletons based on the go language gin framework, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!