将Web框架迁移到Gin

- 安装Gin框架 v1.11.0
- 重构main.go使用Gin路由器
- 更新handlers使用gin.Context
- 重构middleware使用Gin中间件模式
- 更新项目文档(README.md, CLAUDE.md)

项目现已准备好进行数据库集成和前端集成

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
yanlongqi 2025-11-03 11:48:39 +08:00
parent 0361f207db
commit 805c4597af
7 changed files with 219 additions and 64 deletions

View File

@ -4,28 +4,34 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## Project Overview ## Project Overview
AnKao is a Go web application built using the standard library's `net/http` package. The project follows a clean architecture pattern with clear separation of concerns. AnKao is a Go web application built using the **Gin framework**. The project follows a clean architecture pattern with clear separation of concerns and is designed to support database integration.
## Architecture ## Architecture
### Request Flow ### Request Flow
1. HTTP requests arrive at the server running on port 8080 1. HTTP requests arrive at the Gin server running on port 8080
2. Requests pass through the `Logger` middleware (in `internal/middleware/`) 2. Requests pass through Gin's default middleware (Logger, Recovery) and custom middleware
3. The router (`http.NewServeMux`) directs requests to appropriate handlers 3. The Gin router matches routes and directs requests to appropriate handlers
4. Handlers (in `internal/handlers/`) process requests and return JSON responses 4. Handlers (in `internal/handlers/`) process requests using `*gin.Context` and return JSON responses
### Middleware Pattern ### Middleware Pattern
Middleware functions wrap the main handler using the standard middleware pattern: Middleware in Gin uses the `gin.HandlerFunc` pattern:
```go ```go
func Middleware(next http.Handler) http.Handler func MiddlewareName() gin.HandlerFunc {
return func(c *gin.Context) {
// Pre-processing
c.Next()
// Post-processing
}
}
``` ```
Middleware is applied in [cmd/server/main.go:20](cmd/server/main.go#L20) before starting the server. Middleware is registered in [main.go:15](main.go#L15) using `r.Use()`.
### Module Structure ### Module Structure
- **cmd/server/** - Application entry point, server configuration and routing setup - **main.go** - Application entry point, server configuration and routing setup
- **internal/handlers/** - HTTP request handlers, all return JSON responses - **internal/handlers/** - HTTP request handlers, all use `*gin.Context` and return JSON responses
- **internal/middleware/** - HTTP middleware chain (currently: logging) - **internal/middleware/** - Gin middleware chain (currently: custom logger)
- **internal/models/** - Data models (directory exists but not yet populated) - **internal/models/** - Data models (directory exists, ready for database models)
- **pkg/config/** - Configuration management (directory exists but not yet populated) - **pkg/config/** - Configuration management (directory exists but not yet populated)
## Common Commands ## Common Commands
@ -33,7 +39,7 @@ Middleware is applied in [cmd/server/main.go:20](cmd/server/main.go#L20) before
### Development ### Development
```bash ```bash
# Run the server # Run the server
go run cmd/server/main.go go run main.go
# Install/update dependencies # Install/update dependencies
go mod tidy go mod tidy
@ -48,7 +54,7 @@ go vet ./...
### Building ### Building
```bash ```bash
# Build binary to bin/server # Build binary to bin/server
go build -o bin/server cmd/server/main.go go build -o bin/server.exe main.go
# Run built binary (Windows) # Run built binary (Windows)
.\bin\server.exe .\bin\server.exe
@ -67,12 +73,34 @@ go test -cover ./...
# Run tests in a specific package # Run tests in a specific package
go test ./internal/handlers/ go test ./internal/handlers/
# Run tests with verbose output
go test -v ./...
``` ```
## Key Implementation Details ## Key Implementation Details
- The server listens on port **:8080** (hardcoded in main.go:23) - **Framework**: Using Gin v1.11.0
- All responses are JSON with appropriate Content-Type headers - **Server Port**: :8080 (configured in [main.go:22](main.go#L22))
- Import paths use the module name `ankao` (defined in go.mod) - **Handler Signature**: All handlers use `func(c *gin.Context)` pattern
- When adding new handlers, register them in [cmd/server/main.go](cmd/server/main.go) using `mux.HandleFunc()` - **JSON Response**: Use `c.JSON()` method with `gin.H{}` or structs
- Middleware wraps the entire mux, so it applies to all routes - **Import Paths**: Use module name `ankao` (defined in go.mod)
- **Route Registration**: Routes are registered in [main.go](main.go) using `r.GET()`, `r.POST()`, etc.
- **Middleware**: Applied globally with `r.Use()` or per-route with route grouping
## Adding New Features
### Adding a New Handler
1. Create handler function in `internal/handlers/` with signature `func(c *gin.Context)`
2. Use `c.JSON()` to return responses
3. Register route in [main.go](main.go) (e.g., `r.GET("/path", handlers.YourHandler)`)
### Adding Middleware
1. Create middleware in `internal/middleware/` returning `gin.HandlerFunc`
2. Apply globally with `r.Use(middleware.YourMiddleware())` or to route groups
### Database Integration
The project is ready for database integration:
- Add models in `internal/models/`
- Consider using GORM or similar ORM
- Add database initialization in main.go or separate package

View File

@ -1,14 +1,12 @@
# AnKao Web 项目 # AnKao Web 项目
这是一个使用Go语言构建的Web应用项目。 这是一个使用Go语言和Gin框架构建的Web应用项目。
## 项目结构 ## 项目结构
``` ```
AnKao/ AnKao/
├── cmd/ ├── main.go # 主程序入口
│ └── server/ # 主程序入口
│ └── main.go
├── internal/ # 私有应用代码 ├── internal/ # 私有应用代码
│ ├── handlers/ # HTTP请求处理器 │ ├── handlers/ # HTTP请求处理器
│ ├── middleware/ # 中间件 │ ├── middleware/ # 中间件
@ -24,7 +22,7 @@ AnKao/
### 运行服务器 ### 运行服务器
```bash ```bash
go run cmd/server/main.go go run main.go
``` ```
服务器将在 `http://localhost:8080` 启动 服务器将在 `http://localhost:8080` 启动
@ -45,18 +43,29 @@ go mod tidy
### 构建 ### 构建
```bash ```bash
go build -o bin/server cmd/server/main.go go build -o bin/server.exe main.go
``` ```
### 运行编译后的程序 ### 运行编译后的程序
```bash ```bash
# Windows
.\bin\server.exe
# Linux/Mac
./bin/server ./bin/server
``` ```
## 特性 ## 特性
- 基于标准库的HTTP服务器 - 基于 Gin 框架的高性能 HTTP 服务器
- 日志中间件 - 自定义日志中间件
- RESTful API 结构 - RESTful API 结构
- 健康检查端点 - 健康检查端点
- 支持数据库集成(预留结构)
## 技术栈
- **Go** 1.25.1
- **Gin** v1.11.0 - Web 框架
- 清晰的项目架构,易于扩展

36
go.mod
View File

@ -1,3 +1,39 @@
module ankao module ankao
go 1.25.1 go 1.25.1
require (
github.com/bytedance/gopkg v0.1.3 // indirect
github.com/bytedance/sonic v1.14.2 // indirect
github.com/bytedance/sonic/loader v0.4.0 // indirect
github.com/cloudwego/base64x v0.1.6 // indirect
github.com/gabriel-vasile/mimetype v1.4.11 // indirect
github.com/gin-contrib/sse v1.1.0 // indirect
github.com/gin-gonic/gin v1.11.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.28.0 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/goccy/go-yaml v1.18.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/quic-go/qpack v0.5.1 // indirect
github.com/quic-go/quic-go v0.55.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.3.1 // indirect
go.uber.org/mock v0.6.0 // indirect
golang.org/x/arch v0.22.0 // indirect
golang.org/x/crypto v0.43.0 // indirect
golang.org/x/mod v0.29.0 // indirect
golang.org/x/net v0.46.0 // indirect
golang.org/x/sync v0.17.0 // indirect
golang.org/x/sys v0.37.0 // indirect
golang.org/x/text v0.30.0 // indirect
golang.org/x/tools v0.38.0 // indirect
google.golang.org/protobuf v1.36.10 // indirect
)

84
go.sum Normal file
View File

@ -0,0 +1,84 @@
github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M=
github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM=
github.com/bytedance/sonic v1.14.2 h1:k1twIoe97C1DtYUo+fZQy865IuHia4PR5RPiuGPPIIE=
github.com/bytedance/sonic v1.14.2/go.mod h1:T80iDELeHiHKSc0C9tubFygiuXoGzrkjKzX2quAx980=
github.com/bytedance/sonic/loader v0.4.0 h1:olZ7lEqcxtZygCK9EKYKADnpQoYkRQxaeY2NYzevs+o=
github.com/bytedance/sonic/loader v0.4.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=
github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gabriel-vasile/mimetype v1.4.11 h1:AQvxbp830wPhHTqc1u7nzoLT+ZFxGY7emj5DR5DYFik=
github.com/gabriel-vasile/mimetype v1.4.11/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk=
github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.28.0 h1:Q7ibns33JjyW48gHkuFT91qX48KG0ktULL6FgHdG688=
github.com/go-playground/validator/v10 v10.28.0/go.mod h1:GoI6I1SjPBh9p7ykNE/yj3fFYbyDOpwMn5KXd+m2hUU=
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
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/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
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/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
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/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
github.com/quic-go/quic-go v0.55.0 h1:zccPQIqYCXDt5NmcEabyYvOnomjs8Tlwl7tISjJh9Mk=
github.com/quic-go/quic-go v0.55.0/go.mod h1:DR51ilwU1uE164KuWXhinFcKWGlEjzys2l8zUl5Ss1U=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY=
github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
golang.org/x/arch v0.22.0 h1:c/Zle32i5ttqRXjdLyyHZESLD/bB90DCU1g9l/0YBDI=
golang.org/x/arch v0.22.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A=
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -1,26 +1,22 @@
package handlers package handlers
import ( import (
"encoding/json"
"net/http" "net/http"
"github.com/gin-gonic/gin"
) )
// HomeHandler 首页处理器 // HomeHandler 首页处理器
func HomeHandler(w http.ResponseWriter, r *http.Request) { func HomeHandler(c *gin.Context) {
w.Header().Set("Content-Type", "application/json") c.JSON(http.StatusOK, gin.H{
response := map[string]string{
"message": "欢迎使用AnKao Web服务", "message": "欢迎使用AnKao Web服务",
"version": "1.0.0", "version": "1.0.0",
} })
json.NewEncoder(w).Encode(response)
} }
// HealthCheckHandler 健康检查处理器 // HealthCheckHandler 健康检查处理器
func HealthCheckHandler(w http.ResponseWriter, r *http.Request) { func HealthCheckHandler(c *gin.Context) {
w.Header().Set("Content-Type", "application/json") c.JSON(http.StatusOK, gin.H{
w.WriteHeader(http.StatusOK)
response := map[string]string{
"status": "healthy", "status": "healthy",
} })
json.NewEncoder(w).Encode(response)
} }

View File

@ -2,25 +2,29 @@ package middleware
import ( import (
"log" "log"
"net/http"
"time" "time"
"github.com/gin-gonic/gin"
) )
// Logger 日志中间件 // Logger 日志中间件
func Logger(next http.Handler) http.Handler { func Logger() gin.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return func(c *gin.Context) {
start := time.Now() start := time.Now()
// 调用下一个处理器 // 处理请求
next.ServeHTTP(w, r) c.Next()
// 记录请求信息 // 记录请求信息
duration := time.Since(start)
log.Printf( log.Printf(
"%s %s %s %v", "[%s] %s %s | %d | %v | %s",
r.Method, c.Request.Method,
r.RequestURI, c.Request.RequestURI,
r.RemoteAddr, c.ClientIP(),
time.Since(start), c.Writer.Status(),
duration,
c.Errors.String(),
) )
}) }
} }

24
main.go
View File

@ -1,28 +1,26 @@
package main package main
import ( import (
"log"
"net/http"
"ankao/internal/handlers" "ankao/internal/handlers"
"ankao/internal/middleware" "ankao/internal/middleware"
"github.com/gin-gonic/gin"
) )
func main() { func main() {
// 创建路由 // 创建Gin路由器
mux := http.NewServeMux() r := gin.Default()
// 应用自定义中间件
r.Use(middleware.Logger())
// 注册路由 // 注册路由
mux.HandleFunc("/", handlers.HomeHandler) r.GET("/", handlers.HomeHandler)
mux.HandleFunc("/api/health", handlers.HealthCheckHandler) r.GET("/api/health", handlers.HealthCheckHandler)
// 应用中间件
handler := middleware.Logger(mux)
// 启动服务器 // 启动服务器
port := ":8080" port := ":8080"
log.Printf("服务器启动在端口 %s", port) if err := r.Run(port); err != nil {
if err := http.ListenAndServe(port, handler); err != nil { panic("服务器启动失败: " + err.Error())
log.Fatal("服务器启动失败:", err)
} }
} }