Reputation: 3844
I am looking for a good project organization for a multi-platform project with multiple components written in Go. I am aware of the recommended layout from http://golang.org/doc/code.html, but the layout suggested there does not seem to fit my requirements.
Project components are:
My requirements are:
My current approach:
project/ (this is the repository root)
server/
server.go (package main)
src/
server/
package1/
package1.go
...
client/
client.go (package main)
src/
client/
package2/
package2.go
...
lib/
src/
lib/
lib.go
...
client-ios/
...
client-android/
...
To build, I use a Makefile which
It works, but feels really klunky and is quite different to the recommended code layout.
Here is the alternative I am considering:
project/ (this is the repository root)
gospace/
src/
server/...
client/...
lib/...
client-ios/
...
client-android/
...
With this layout I have a single GOPATH (gospace/) and don't need the klunky Makefile. However, the components are not separated as neatly as in the first alternative (i.e. via a top level directory).
My question: Which project layout would be best suited for both my requirements and Go conventions and tooling support? Are there better options which I did not see yet?
Upvotes: 8
Views: 4254
Reputation: 155
It's been a long time since this question was answered (last comment on OP was Feb. 12, 2014, and the latest answer was Apr. 16, 2014). I wasn't around for the state of Go at that time, only really being introduced to it in 2018/19, yet it looks like a lot has changed.
The biggest change that influences the answer to this post, I believe, is Go Modules.
I have a similar project in the works (Go server, Go CLI, Android app, iOS app). I am currently using go version go1.13.7 darwin/amd64. Here is the structure I came with via Go Modules (very much influenced by this post by Ben Johnson):
directory-outside-GOPATH/
go.mod
go.sum
domaintypes.go
cmd/
api/
main.go
cli/
main.go
postgres/
...(library Go code)...
http/
...(library Go code)...
android/
...(Android app)...
iOS/
...(iOS app)...
...(other Go code).../
...
The root directory sits outside of the GOPATH and includes the necessary go.mod
and go.sum
files. The domaintypes.go
file is to illustrate that the only Go files I leave in the root directory is code that will never import anything else - such as defining your domain types/models/service-interfaces/etc. I personally have multiple: user.go
, group.go
, etc.
The postgres
and http
directories are libraries I have written, both of which are layered adapters. Each library directory should be isolated to its domain. e.g. HTTP routes should not directly interact with database connections.
The cmd
directory is where all executable Go code should live. I want an API server and a separate CLI so this is where that lives. These files should remain relatively small and call all of the other libraries you wrote.
As for the non-Go code, I simply created separate directories in the root directory for both Android and iOS.
Upvotes: 3
Reputation: 99431
This is how I organized a similar project :
$GOPATH/src/project-root/
lib.go
lib_test.go
server/
server.go
server_test.go
main/
server.go // package main; import "project-root/server"
client/
client.go
client_test.go
main/
client.go //package main; import "project-root/client"
client-ios/
....
client-android/
....
While mostly having server/server.go
and client/client.go
as package main
should work, it's better to separate it so you could embed the client/server in other projects.
Upvotes: 6