Golang项目目录结构设计规范

各位Golang开发者,想请教下关于项目目录结构设计的规范问题。目前团队在开发一个中型规模的Golang项目,对于如何组织代码目录有些困惑。比如:

  1. 应该采用平铺式结构还是分层式结构更合适?
  2. 第三方依赖和内部模块应该如何划分目录?
  3. 测试代码应该和业务代码放在一起还是单独目录?
  4. 大型项目中常见的目录划分模式有哪些最佳实践?

希望能得到一些实际项目中的经验分享,特别是针对不同规模项目的目录结构设计建议。

2 回复

Golang项目目录结构建议遵循简洁、可维护原则:

  1. 标准布局(参考Go官方建议):

    • /cmd:存放应用入口文件,每个子目录对应一个可执行程序
    • /internal:私有代码,禁止外部项目导入
    • /pkg:可供外部使用的库代码
    • /api:API协议定义文件(如protobuf/swagger)
    • /web:Web应用相关静态资源
  2. 常见目录

    • /configs:配置文件模板
    • /scripts:构建/安装脚本
    • /build:打包和持续集成文件
    • /test:额外测试文件
    • /vendor:依赖包(go mod后可选)
  3. 文件规范

    • go.mod置于项目根目录
    • 避免过度分层,保持扁平化
    • 按功能而非层级组织包

关键原则:保持简单直观,便于团队协作和代码复用。

更多关于Golang项目目录结构设计规范的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Golang项目中,合理的目录结构设计能提高代码可读性、可维护性和团队协作效率。以下是推荐的Golang项目目录结构规范,适用于中小型项目和微服务架构:

标准目录结构

project-name/
├── cmd/                 # 应用程序入口目录
│   └── app-name/        # 每个可执行程序一个子目录
│       └── main.go      # main函数入口
├── internal/            # 私有应用程序代码(禁止外部导入)
│   ├── handler/         # HTTP处理层
│   ├── service/         # 业务逻辑层
│   ├── repository/      # 数据访问层
│   └── model/           # 数据模型
├── pkg/                 # 公共库代码(可被外部项目导入)
│   ├── utils/           # 通用工具函数
│   └── logger/          # 日志组件
├── api/                 # API定义文件(Protobuf/Swagger)
├── configs/             # 配置文件
├── deployments/         # 部署配置(Docker/K8s)
├── scripts/             # 构建/安装脚本
├── build/               # 构建输出目录
├── test/                # 额外测试文件
├── docs/                # 文档
├── go.mod              # 模块定义
└── README.md           # 项目说明

核心目录说明

  1. cmd/
// cmd/app/main.go
package main

import "project-name/internal/app"

func main() {
    app.Run()
}
  1. internal/
  • handler/: HTTP请求处理
// internal/handler/user.go
package handler

type UserHandler struct {
    service UserService
}

func (h *UserHandler) GetUser(c *gin.Context) {
    // 处理请求
}
  • service/: 业务逻辑
// internal/service/user.go
package service

type UserService struct {
    repo UserRepository
}

func (s *UserService) GetUser(id int) (*model.User, error) {
    return s.repo.FindByID(id)
}
  • repository/: 数据持久化
// internal/repository/user.go
package repository

type UserRepository struct {
    db *gorm.DB
}

func (r *UserRepository) FindByID(id int) (*model.User, error) {
    var user model.User
    err := r.db.First(&user, id).Error
    return &user, err
}
  1. pkg/
// pkg/utils/stringutil.go
package utils

func Reverse(s string) string {
    runes := []rune(s)
    for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
        runes[i], runes[j] = runes[j], runes[i]
    }
    return string(runes)
}

最佳实践

  1. 依赖方向: internal内按handler→service→repository单向依赖
  2. 包命名: 使用单数形式,避免util、common等泛化名称
  3. 模块划分: 大型项目可按领域划分internal子目录
  4. 配置管理: 使用环境变量+配置文件组合

微服务变体

对于微服务项目,可简化为:

service-name/
├── cmd/
├── internal/
│   ├── api/          # 传输层
│   ├── domain/       # 领域层
│   └── infrastructure/# 基础设施
└── pkg/

这种结构符合Go社区约定,便于新成员快速理解项目架构。实际应用中可根据项目规模适当调整,保持结构清晰和一致性最重要。

回到顶部