How to structure a golang project with several go modules: a "core" module, and some "adapter" modules referencing the "core" one?

huangapple go评论85阅读模式
英文:

How to structure a golang project with several go modules: a "core" module, and some "adapter" modules referencing the "core" one?

问题

很难用一句话概括,但是这是情况。我正在开发一个Go语言包,我的意图是使其能够通过"go get"命令获取。该包的核心提供了一些"中心"功能,即一个HTTP中间件。我需要几个"适配器"包来支持一些最著名的Go语言HTTP框架。

每个适配器的责任是从HTTP请求中获取所需的信息,然后调用核心服务来处理逻辑。因此,主要逻辑位于一个地方,而每个适配器则充当适配器的角色。

我能想到的第一种方法是将核心和适配器都作为同一个模块的一部分,但这将给导入项目添加很多不必要的依赖项。例如,如果您想导入该包以支持"框架A",该包将间接添加其他框架适配器所需的所有依赖项,即使不使用这些适配器。

我考虑的方法是在同一个包中拥有多个模块:一个核心模块和一个适配器模块。然后,每个适配器模块将导入核心模块:

|- core
|  |- go.mod
|
|- adapter1
|  |- go.mod
|
|- adapter2
   |- go.mod

这样,适配器1模块可以被导入,并且只会携带它自己的依赖项和核心模块的依赖项,而适配器2的依赖项则不会被考虑。

我在本地使这个结构工作了:我可以成功地从另一个Go项目中使用go mod replace语句导入适配器1或适配器2,但是当我将更改推送到git仓库并尝试直接从那里导入时,我无法让go mod下载每个包的最新版本/标签,即使我明确提供要使用的版本标签。它始终下载旧版本,并抱怨一些缺失的代码部分(这些代码部分只存在于最新版本中)。

我按照这篇关于在单个仓库中引用多个模块的指南进行操作,但一个重要的区别是,在我的情况下,我正在引用一个引用同一仓库中的另一个模块的模块,而指南中的示例展示了如何独立引用模块。

所以我的问题是,是否有可能引用一个引用同一仓库中的另一个Go模块的Go模块?

将我的"核心"模块放在一个单独的仓库中,然后在一个"适配器"仓库/模块中为每个适配器创建一个包,这样做是否更好?

将所有内容放在同一个仓库中的目的是为了简化开发,但这给版本控制带来了很多复杂性。

非常感谢您提供的任何建议。如果您需要我澄清某些内容,我将非常乐意这样做。谢谢!

英文:

Hard to put in a single sentence, but here is the situation. I am developing a golang package, my intention is for it to be go-gettable. The core of the package provides some "central" functionality, an http middleware. And I need several "adapter" packages to support some of the most famous golang http frameworks.

Each adapter responsibility is to get the required information from the http request and then consume a core service where the logic resides. So the main logic resides in a single place while each adapter acts like, well, an adapter.

The first approach I can think of is to have both the core and adapters as part of the same module, but this will add a lot of unnecessary dependencies to the importing project. For instance, if you want to import the package to support framework A the package will indirectly add all the dependencies required by the adapters for other frameworks, even when not used.

The approach I am considering is to have several modules in the same package: a core module and a separate module for each adapter. Each adapter module will then import the core module:

|- core
|  |- go.mod
|
|- adapter1
|  |- go.mod
|
|- adapter2
   |- go.mod

This way, adapter 1 module could be imported and will only carry it's dependencies and those of the core module, leaving adapter 2 dependencies out of the picture.

I got this structure to work locally: I can successfully import adapter 1, or adapter 2, from another golang project using go mod replace statement but when I push changes to the git repo and try to import directly from there I can't get go mod to download the latest version/tag of each package, not even by explicitly providing the version tag I want to use. It keeps downloading an older version and complaining about some missing code parts (that exist only in the latest version).

I followed this guide on sourcing multiple modules on a single repository but an important distinction is that in my case, I am sourcing a module that references another module in the same repo, while the example in the guide shows how to source modules independently.

So my question is, is it at all possible to source a go module that references another go module on the same repo?

Would it be a better approach to have my "core" module on a separate repository and then an "adapters" repo/module with a package for each adapter?

The purpose of having it all in the same repo is to make the development easier, but it is complicating version control a lot.

Any advice will be greatly appreciated. If you need me to clarify something I would gladly do so. Thanks in advance.

答案1

得分: 1

考虑到在你的go.mod文件中使用replace指令(issue 44840)将导致任何go install操作无法进行。

这将导致以下错误信息:

提供命名包的模块的go.mod文件包含一个或多个replace指令。

它不能包含会导致其与主模块解释方式不同的指令。

因此,最好每个仓库使用一个模块,并且你可以将这些仓库组合到一个父Git仓库中(通过submodules,每个仓库都跟踪一个分支以便于更新)以提高便利性。

英文:

Consider that any go install would not be possible with a replace directive in your go.mod (issue 44840).

That would result in the error message:

The go.mod file for the module providing named packages contains one or more 
replace directives. 

It must not contain directives that would cause	it to be interpreted differently 
than if it were the main module.

So one module per repositories is preferable, and you can then group your repositories into one parent Git repository (through submodules, each one following a branch for easy update) for convenience.

huangapple
  • 本文由 发表于 2022年3月29日 11:31:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/71656124.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定