I'm at an initial stage of creating a microservice application in Go, but due to the way that the import paths and directories are handled I'm not quite sure what's best way to structure the project files.
Normally, the project would look something like this in Java:
|-- gateway_microservice
|-- src
|-- docker
|-- config_microservice
|-- src
|-- docker
|-- recommendation_microservice
|-- src
|-- docker
|-- users_microservice
|-- src
|-- docker
Now if I do it the same way in Go, the import paths become somewhat cumbersome:
import (
"fmt"
"github.com/user/myproject/gateway_microservice/src/package1"
"github.com/user/myproject/gateway_microservice/src/package2"
)
Additionally, I hear that the idiomatic way is to put all main.go
files in a separate cmd
directory, which adds to the confusion. Would it look something like this:
|-- cmd
|-- gateway_microservice
|-- main.go
|-- config_microservice
|-- main.go
|-- recommendation_microservice
|-- main.go
|-- users_microservice
|-- main.go
|-- gateway_microservice
|-- src
|-- docker
|-- config_microservice
|-- src
|-- docker
|-- recommendation_microservice
|-- src
|-- docker
|-- users_microservice
|-- src
|-- docker
What is the 'correct' or idiomatic way of structuring a project like this in Go?
The other answer here advocates putting each microservice into its own repository. There may be valid reasons for splitting things up that way, but there may be equally valid reasons from wanting to keep everything in one repository as well (it really depends on your project / circumstances)
If you want all the code in one repository, you can- you just need to follow Go's package rules. (this is a good read: https://golang.org/doc/code.html#Workspaces)
If you have a mix of commands and libraries, the directory structure you proposed in your question comes close, but you probably don't need the src
directories in there. Here's an example of how a directory structure within a repo with libraries and commands might look:
lib1/
-- some.go
-- source.go
lib2/
-- more.go
-- source.go
cmd/
-- microservice1/
-- main.go
-- microservice2/
-- anothermain.go
To use this repository, you would clone it inside a Go workspace on your system (see the link I shared above). Assuming your repository lives in github.com/mybiz/project, and your GOPATH
was ~/go
, the workspace would look as follows:
~/go/src/github.com/mybiz/
-- project/
<clone repo in here>
The file cmd/microservice1/main.go
would include the library lib1
via a path it expects it in relative to $GOPATH/src
as follows:
import "github.com/mybiz/project/lib1"
Now, your code has access to the exported symbols in that package using the package name declared in the files under lib1
... usually just:
package lib1
In cmd/microservice1/main.go
, with the import above, you could use lib1
symbols as follows:
lib1.CallMe()
I hope that helps clear up how Go's directory structure works.