1

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.

Jairo Lozano
  • 3,883
  • 3
  • 20
  • 29
  • 3
    The dependency graph is through packages, not modules. If all if the packages are versioned together, then put the packages in a single module. –  Mar 29 '22 at 04:02
  • 2
    "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." is a wrong statement. Your whole argument and question is unsound. Use one module. – Volker Mar 29 '22 at 04:06
  • Thanks for your comments. So, if moduleA requires only moduleB.package1 (but no moduleB.package2), moduleB.package2 dependencies won't be imported to moduleA? Even though they appear in the go.sum file. I've tried to answer this myself but can't find an explicit answer, I just want to avoid creating unnecessary dependencies. – Jairo Lozano Mar 29 '22 at 19:05

1 Answers1

1

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.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250