Golang构建电商网站的最佳结构实践

Golang构建电商网站的最佳结构实践 我刚开始学习 Golang,想尝试制作一个网站。

我不关心控制台部分。

我对文件夹结构有些疑问。我在网上找到了一些建议,但每个人的想法都不同。简而言之,我比之前更困惑了。

目前我理解到的结构应该是这样的:

  • ProjectFolder – bin – pkg – src

有人能向我解释一下如何构建一个网站,特别是电子商务网站的结构吗?

提前感谢!

2 回复

Luc: 有人能向我解释一下如何构建一个网站,比如电子商务网站吗?

以下是我构建一个常规网站的结构示例:在您的计算机上安装Go

更多关于Golang构建电商网站的最佳结构实践的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


对于电商网站,推荐使用分层架构(Clean Architecture/DDD风格)。以下是经过生产验证的目录结构:

project/
├── cmd/
│   └── server/
│       └── main.go          # 应用入口
├── internal/                # 私有代码(外部无法导入)
│   ├── domain/              # 领域层
│   │   ├── entity/          # 核心业务实体
│   │   │   ├── product.go
│   │   │   └── order.go
│   │   └── valueobject/     # 值对象
│   │       └── money.go
│   ├── application/         # 应用层
│   │   ├── service/         # 用例服务
│   │   │   ├── cart_service.go
│   │   │   └── payment_service.go
│   │   └── dto/             # 数据传输对象
│   │       └── cart_dto.go
│   ├── infrastructure/      # 基础设施层
│   │   ├── persistence/     # 持久化
│   │   │   ├── repository/  # 仓储接口实现
│   │   │   │   ├── product_repository.go
│   │   │   │   └── order_repository.go
│   │   │   └── models/      # 数据库模型
│   │   │       └── product_model.go
│   │   ├── http/            # HTTP传输层
│   │   │   ├── handler/     # HTTP处理器
│   │   │   │   ├── product_handler.go
│   │   │   │   └── order_handler.go
│   │   │   ├── middleware/  # 中间件
│   │   │   │   └── auth.go
│   │   │   └── router.go    # 路由定义
│   │   └── cache/           # 缓存实现
│   │       └── redis.go
│   └── config/              # 配置
│       └── config.go
├── pkg/                     # 可公开的库代码
│   ├── logger/              # 日志包
│   └── utils/               # 工具函数
├── api/                     # API定义
│   └── openapi/             # OpenAPI文档
├── migrations/              # 数据库迁移
│   └── 001_init_schema.sql
├── Dockerfile
├── go.mod
└── go.sum

核心代码示例:

领域实体 (internal/domain/entity/product.go):

package entity

import "errors"

type Product struct {
    ID          string
    Name        string
    Description string
    Price       Money
    Stock       int
    Category    string
}

func (p *Product) ReduceStock(quantity int) error {
    if p.Stock < quantity {
        return errors.New("insufficient stock")
    }
    p.Stock -= quantity
    return nil
}

仓储接口 (internal/domain/repository/product_repository.go):

package repository

import "github.com/yourproject/internal/domain/entity"

type ProductRepository interface {
    FindByID(id string) (*entity.Product, error)
    Save(product *entity.Product) error
    FindByCategory(category string) ([]*entity.Product, error)
}

HTTP处理器 (internal/infrastructure/http/handler/product_handler.go):

package handler

import (
    "net/http"
    "github.com/gin-gonic/gin"
    "github.com/yourproject/internal/application/service"
)

type ProductHandler struct {
    productService *service.ProductService
}

func (h *ProductHandler) GetProduct(c *gin.Context) {
    id := c.Param("id")
    product, err := h.productService.GetProduct(id)
    if err != nil {
        c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
        return
    }
    c.JSON(http.StatusOK, product)
}

func (h *ProductHandler) CreateProduct(c *gin.Context) {
    var req CreateProductRequest
    if err := c.ShouldBindJSON(&req); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }
    
    product, err := h.productService.CreateProduct(req)
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
        return
    }
    
    c.JSON(http.StatusCreated, product)
}

应用入口 (cmd/server/main.go):

package main

import (
    "github.com/gin-gonic/gin"
    "github.com/yourproject/internal/config"
    "github.com/yourproject/internal/infrastructure/http"
    "github.com/yourproject/internal/infrastructure/persistence"
)

func main() {
    // 加载配置
    cfg := config.Load()
    
    // 初始化依赖
    db := persistence.NewDatabase(cfg.Database)
    productRepo := persistence.NewProductRepository(db)
    
    // 创建HTTP服务器
    router := gin.Default()
    http.RegisterRoutes(router, productRepo)
    
    // 启动服务器
    router.Run(":" + cfg.Server.Port)
}

这种结构的关键优势:

  1. 依赖倒置:高层模块不依赖低层模块实现
  2. 可测试性:每层都可以独立测试
  3. 可维护性:业务逻辑集中在domain层
  4. 可扩展性:易于替换基础设施(数据库、缓存等)

对于电商特有的模块,建议添加:

  • internal/domain/service/ - 领域服务(如库存管理、价格计算)
  • internal/infrastructure/payment/ - 支付网关集成
  • internal/infrastructure/email/ - 邮件通知服务

使用 internal 目录可以防止外部项目导入内部实现细节,这是Go 1.4+的标准实践。cmd 目录存放可执行文件入口,pkg 存放可供外部使用的库代码。

回到顶部