Golang中构建Web应用程序的结构设计
Golang中构建Web应用程序的结构设计
project:
/internal
/src
/routs
/controller
/service
/database
/utils
/pkg
main.go
go.mod
.env
.env.example
Makefile
我正在尝试为学习目的构建一个简单的微服务,我设计的结构如上所示。任何建议都将非常有帮助。提前感谢。
1 回复
更多关于Golang中构建Web应用程序的结构设计的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
对于你设计的Golang Web应用程序结构,这里有一些具体的实现示例:
路由层示例 (/src/routes/routes.go):
package routes
import (
"github.com/gin-gonic/gin"
"yourproject/src/controller"
)
func SetupRoutes(router *gin.Engine) {
api := router.Group("/api/v1")
{
userController := controller.NewUserController()
api.GET("/users", userController.GetUsers)
api.POST("/users", userController.CreateUser)
api.GET("/users/:id", userController.GetUserByID)
}
}
控制器层示例 (/src/controller/user_controller.go):
package controller
import (
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"yourproject/src/service"
)
type UserController struct {
userService service.UserService
}
func NewUserController() *UserController {
return &UserController{
userService: service.NewUserService(),
}
}
func (uc *UserController) GetUsers(c *gin.Context) {
users, err := uc.userService.GetAllUsers()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, users)
}
func (uc *UserController) GetUserByID(c *gin.Context) {
id, _ := strconv.Atoi(c.Param("id"))
user, err := uc.userService.GetUserByID(id)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
return
}
c.JSON(http.StatusOK, user)
}
服务层示例 (/src/service/user_service.go):
package service
import (
"yourproject/src/database"
"yourproject/src/database/models"
)
type UserService interface {
GetAllUsers() ([]models.User, error)
GetUserByID(id int) (*models.User, error)
CreateUser(user *models.User) error
}
type userService struct {
userRepo database.UserRepository
}
func NewUserService() UserService {
return &userService{
userRepo: database.NewUserRepository(),
}
}
func (us *userService) GetAllUsers() ([]models.User, error) {
return us.userRepo.FindAll()
}
func (us *userService) GetUserByID(id int) (*models.User, error) {
return us.userRepo.FindByID(id)
}
数据层示例 (/src/database/user_repository.go):
package database
import (
"gorm.io/gorm"
"yourproject/src/database/models"
)
type UserRepository interface {
FindAll() ([]models.User, error)
FindByID(id int) (*models.User, error)
Create(user *models.User) error
}
type userRepository struct {
db *gorm.DB
}
func NewUserRepository() UserRepository {
return &userRepository{
db: GetDB(),
}
}
func (ur *userRepository) FindAll() ([]models.User, error) {
var users []models.User
result := ur.db.Find(&users)
return users, result.Error
}
func (ur *userRepository) FindByID(id int) (*models.User, error) {
var user models.User
result := ur.db.First(&user, id)
return &user, result.Error
}
模型定义 (/src/database/models/user.go):
package models
import "gorm.io/gorm"
type User struct {
gorm.Model
Name string `json:"name" gorm:"size:100"`
Email string `json:"email" gorm:"uniqueIndex;size:255"`
Password string `json:"-" gorm:"size:255"`
}
数据库连接 (/src/database/database.go):
package database
import (
"fmt"
"log"
"os"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"yourproject/src/database/models"
)
var db *gorm.DB
func InitDB() {
dsn := fmt.Sprintf(
"host=%s user=%s password=%s dbname=%s port=%s sslmode=disable",
os.Getenv("DB_HOST"),
os.Getenv("DB_USER"),
os.Getenv("DB_PASSWORD"),
os.Getenv("DB_NAME"),
os.Getenv("DB_PORT"),
)
var err error
db, err = gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatal("Failed to connect to database:", err)
}
// Auto migrate models
db.AutoMigrate(&models.User{})
}
func GetDB() *gorm.DB {
return db
}
主程序 (main.go):
package main
import (
"log"
"github.com/gin-gonic/gin"
"yourproject/src/database"
"yourproject/src/routes"
"github.com/joho/godotenv"
)
func main() {
// Load environment variables
if err := godotenv.Load(); err != nil {
log.Println("No .env file found")
}
// Initialize database
database.InitDB()
// Setup router
router := gin.Default()
// Setup routes
routes.SetupRoutes(router)
// Start server
port := ":8080"
log.Printf("Server starting on port %s", port)
router.Run(port)
}
工具函数示例 (/src/utils/jwt_util.go):
package utils
import (
"time"
"github.com/golang-jwt/jwt/v4"
)
func GenerateJWT(userID uint, email string) (string, error) {
claims := jwt.MapClaims{
"user_id": userID,
"email": email,
"exp": time.Now().Add(time.Hour * 24).Unix(),
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString([]byte("your-secret-key"))
}
这个结构实现了清晰的关注点分离:路由处理HTTP请求分发,控制器处理请求/响应逻辑,服务层包含业务逻辑,数据层处理数据库操作。

