So, newbie to Go here, and I’m working on porting a small web service I wrote in Python to Go. The python version consisted of a single Flask app, with handlers for a REST API that indexed data in Elasticsearch, and a dashboard that provides system status and basic data/search views.
My first attempt in Go sort of replicated that model: one flat package (“main”) written with Gin and elastigo. The package consists of a half-dozen files, and implements the REST api and the dashboard handlers, along with some backend abstractions.
Now I’d like to separate the web service from the dashboard service so that I can work on scaling the rest API, but run the management dashboard by itself, and I’m not sure how to do it. Each binary will need it’s own “main” package, but I want all the code in one repository as there is code that should be shared. Any tips?
In addition to @NateFinch’s comment, I see many projects putting all their main packages together in one directory and it’s frequently called cmd. Two examples off the top of my head are Kubernetes and Camlistore.
Also, I’ve seen other projects mapping all the available commands in one single program, e.g. Hashicorp seems to follow this pattern across all their projects (Consul, Terraform, etc…).
etcd takes a different approach. The root package is a complete program but also its subpackage etcdctl.
I had a similar dilemma and went for this suggestion. I don’t know if it’s the best one, but it I think it covers the exact same issue. There was another suggestion later to keep the command line ui in the root of the project, but I have yet to decide whether to do it or not.
I’ve seen some projects opting for storing all their packages under a pkg subdirectory. I think that’s a good approach if you don’t want to have a mix of Go packages and other things that still you want to manage in the same repo, like docs, the project website, examples, provisioning stuff, integration tests, etc… Camlistore or Kubernetes do this.
But nothing stops you from putting Go packages and other directories together, e.g. that’s what Prometheus, Heka and others do.
This is something we’ve been fighting and iterating on… Current layout on a reasonably sized project looks like this:
... lots of dependencies. This would probably be vendor/ if we started again today.
... lots of binaries / main packages
... various example configs and stuff
... a web app that is compiled into one of the binaries
... our internal packages, some with subdirectories of their own.
... this was "internal" at some point, but since this is nowadays enforced and we
... actually have a few external uses, it became "lib"
... various build supporting Go scripts
... etc standard toplevel stuff
There are a few more top level directories for stuff like graphics assets and so on as well, but not relevant to the Go side of things. So all the Go code lives under cmd/ and lib/, apart from build scripts.
This all builds with standard GOPATH (plus a prepend for Godeps), so internal packages are seen as github.com/organization/project/lib/thepackage.
I’ve been looking into gb as well, but I’m not entirely convinced yet.