Structuring Go Codes (Our Way)

refactory
3 min readNov 11, 2021

Our first story in Medium — Stop structuring Go codes like Java — was merely a (mild) rant. We apologize if it offends anyone — but if it makes you think twice about how you organize your Go Codes, that story has fulfilled its purpose.

The primary reason I think the Java convention didn’t particularly fit for Go is the fact that Go didn’t have a namespace - it has only a package name that doesn’t have a strict path requirement. This reason alone should stop any sane human being from trying to have an “src” folder and hoping their Jetbrain IDE will allow refactoring any Go codebase as it did for the Java codebase. We loved Jetbrain IDE, don’t get us wrong — but only if we were coding Kotlin.

With that being said out loud, since many comments in our first story ask for our opinion on how Go codebase should be structured, we will try to cover that in this (another) short story.

TLDR;

Go Project Structure

There you have it. This project holds both our Back-end APIs and the web portion of our product: SEV-2. So rather than explaining what each folder is, we would group them along with that category.

Back-end

There are four folders that we use to organize our back-end related codebase. api cmd internal and pkg .

api is where we store our Swagger Spec. During the build, we will generate API docs and eventually serve as a static documentation site.

cmd is the main package folder and will produce the sev2-server binary.

internal is where we place our models, handlers, and utility packages. As the name suggests, all of them are not intended to be exposed to any other external project(s). Expanded, this is how it looks like

internal packages

Those 3 are the main folders that powered our API, with one additional folder pkg that meant exposing all of the API contracts and client functionality to external project(s).

Web

While we have developed both Desktop and Mobile clients for our app, we still need the landing page and sort of Dashboard Console for our users. We have webfolder containing a Svelte app that will be transpiled into static web assets during build, then served statically by the main binary. By having the web assets served as part of the back-end, we could build both the back-end and the web and easily test them both locally.

In the future, it might go into its own repo with its own web-server. For now we just don’t want to overcomplicate things.

Build Tools and CI/CD

We have Makefile and Dockerfile in the root directory as primary build files. Obviously .circleci folder that contains our CI workflow, and deployments folder that contains the helm values that will work for our own Chart.

Build files

You might already familiar with this structure as it very similar to the unofficial golang-standard project layout. So nothing new really.

If we have more time, we will dig down more deeply on our development workflow and the codebase itself — what we like and what we don’t like (i.e go functo Erlang spawn). By writing this up, our intention was solely to signify that Go loose structure should be embraced to fit with your project nature — not by some other language convention 😉

--

--