What is the recommended way in Golang to download a submodule of a dependency? I think my question can be best described by examples.
I have a client and a server. My server is an API and has a bunch of other dependencies, such as databases, messages queues, consul, and etc. I would like my client to be a lightweight package where users download only few dependencies needed for the client.
You could say that the client and server can be on separate repositories. However, there may also be some common code amongst them, which if we follow this pattern, would again be another repository.
I'm thinking of some structure that looks like this:
service/
---> common/
------> redis.go
------> kafka.go
---> client/
------> client.go
---> server/
------> database/
------> swagger/
------> producer/
------> etc/
It's pretty common for projects to share models. If we have microservices that communicate through message brokers with a common model, we'd probably want some structure like this.
service/
---> model/
------> message.go
---> service1/
---> service2/
I am from a Scala/Java background and have started to use Golang less than a month. Comparing with Scala, I could have handled this in two ways. Let's take Example #2
model.jar
in each serviceBut so far they don't seem to solve my question
What is the recommended way in Golang to tackle the issues I stated in the examples?
Thank you for your help!
Generally, try to stick to one repo and one module, as much as possible. Splitting your codebase to multiple repos and/or multiple modules incurs costs that will grow over time. You'll need to define clear version dependencies between your own modules, do phased upgrades carefully, etc. Especially for small-to-medium projects, one repo and one module is the best way to go.
Regarding your specific requirement in Example 1, if it's critical for the users of "client" to not pull "server" code, then client and server will have to be in separate modules. These modules can be either in the same repo or in different repos - this makes no difference to Go. The common code will have to be in a module of its own, e.g.:
github.com/user/myrepo/
client/
go.mod
server/
go.mod
common/
go.mod
Then, a module using your client would have, in their go.mod
:
require github.com/user/myrepo/client <version>
And this will pull in client
and common
, but not server
.
If it's OK for server to depend on client, you could potentially make common
part of client
, though I'm not sure this would save much.
For Example 2 the idea is similar - common code can go into its own module.
I strongly recommend you read the official blog posts on Using Go Modules.
For a simple Go project layout with modules, see this post