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请求分发,控制器处理请求/响应逻辑,服务层包含业务逻辑,数据层处理数据库操作。

回到顶部