Golang中_internal包应该存放哪些内容?

Golang中_internal包应该存放哪些内容? 大家好,

你们通常在 /internal 目录中存放什么内容?是存放验证辅助函数,还是数据库模型?

这与 DDD 范式有何关联?你们会将领域逻辑存放在 /internal 包中吗?

2 回复

你好 @heidi

/internal 目录被 Go 编译器识别为一个特殊目录。/internal 内部的包无法被其他项目访问。

通过将包放入 /internal,你可以减少你的公共 API 表面积

关键在于,如果你的项目是公开的,迟早会有其他人开始使用你项目的公共包,无论你是否打算让所有这些包都被他人复用。这会增加维护负担,并降低你随意更改包 API 的能力。

因此,如果你有一些不希望为他人维护、并且其包 API 很可能发生变化的包,请将它们放入 /internal

(更多关于 Go 项目布局的信息在此。)

更多关于Golang中_internal包应该存放哪些内容?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go项目中,/internal目录用于存放不对外公开的代码,这些代码只能被项目内部的包导入,外部项目无法引用。根据Go 1.4引入的internal机制,其设计目的是保护项目内部实现细节,避免外部依赖。

典型存放内容:

  1. 项目私有工具函数(如验证辅助函数、字符串处理等)
  2. 数据库模型和仓储实现(如果采用DDD,通常存放仓储的具体实现)
  3. 服务层实现细节
  4. 中间件实现
  5. 配置加载逻辑
  6. 领域逻辑的具体实现(在DDD中,领域实体的行为实现)

与DDD的关联:

在DDD架构中:

  • /internal通常存放领域逻辑的具体实现基础设施层代码(如数据库操作)和应用服务实现
  • 领域模型的核心接口(如仓储接口、领域服务接口)通常放在项目根目录或/pkg中对外公开
  • 领域实体本身通常放在/internal中保护其内部状态和行为

示例代码结构:

// 项目结构示例:
myapp/
├── cmd/
│   └── server/
│       └── main.go
├── internal/
│   ├── user/
│   │   ├── repository/      # 仓储实现
│   │   │   └── mysql.go     # MySQL具体实现
│   │   ├── service/         # 应用服务实现
│   │   │   └── service.go
│   │   └── validator/       # 验证辅助函数
│   │       └── validator.go
│   └── pkg/
│       └── crypto/          # 内部加密工具
│           └── aes.go
├── pkg/
│   └── user/                # 对外公开的包
│       ├── repository.go    # 仓储接口
│       └── entity.go        # 实体接口
└── go.mod

// internal/user/validator/validator.go
package validator

import "regexp"

// 内部验证函数,外部无法导入
func ValidateEmail(email string) bool {
    re := regexp.MustCompile(`^[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,4}$`)
    return re.MatchString(email)
}

// internal/user/repository/mysql.go
package repository

import (
    "database/sql"
    "myapp/pkg/user" // 只能导入项目内部的公开包
)

type userRepository struct {
    db *sql.DB
}

// 实现pkg/user中的Repository接口
func (r *userRepository) FindByID(id int) (*user.Entity, error) {
    // 具体数据库查询实现
    return &user.Entity{ID: id}, nil
}

关键原则:

  1. 如果代码需要被其他项目导入使用,应该放在/pkg目录
  2. 如果代码是项目内部实现细节,应该放在/internal
  3. 在DDD中,领域实体的核心行为(方法)可以放在/internal中实现,但接口定义通常对外公开
  4. 数据库模型如果包含业务逻辑,适合放在/internal;如果是简单的DTO,可以考虑放在/pkg

这种结构确保了项目的封装性,同时支持清晰的架构分层。

回到顶部