go-resources/project_structure.md

3.7 KiB

Project Structure

One of Go's strength's is its simplicity. Project structure should be kept simple as well.

A Common Misconception

Although the golang-standards/project-layout repo looks official (23k+ stars, "golang" in the name, etc), it is not. Russ Cox, a principal engineer at Google and the most active contributor to Go has opened an issue to address this.

How Complex is Your Project?

On the complex end of the spectrum, projects like CockroachDB and Kubernetes use a complex project structure. gorilla/mux is comparatively simple. It has no dependencies and has no directory structure. Here are complexity scores for these 3 projects, and a few others, using scc:

Project Lines in .go Files Complexity score
Kubernetes 4,913,049 524,227
CockroachDB 4,064,838 725,465
gitea 223,761 39,001
hugo 148,613 16,642
go-github 117,131 15,637
traefik 107,542 9,154
gio 47,283 5,122
gorilla/mux 6,661 763

The complexity scores are rough estimates, but are useful in realizing how complex your code is. Creating project structure is not a pure science. There is an art to knowing how to lay out a project based on its current state, and its trajectory.

If your project is simple, do not add unnecessary structure. This increases the cognitive load of anyone trying to use the project.

Organize Code by Responsibility

When creating modules and packages, be sure to define what the package's responsibility is. This is encouraged by the standard go practice of having a package comment. Difficulty in defining a responsibility/purpose is a sign of an unnecessary or too broad package.

Package internal

internal is additional complexity, and should really only be used for packages with substantial users. If there are only a few people using the project and it is in development, it may not be necessary to use this.

Use internal packages to reduce your public API surface

Package pkg

pkg should not be used in the package path. It is redudant at best (a package path always leads to a package).

rakyll.org

Organzing Go Code

What's in a Name?

Use Encapsulation Tools to Create Project Structure

Modules, packages, files, funcs, and structs are all encapsulation tools. Use them according to their purpose. Using a package for one exported func (and none unexported) is probably a misuse.

Adding Complexity Should Have a Rationale

Adding packages adds complexity to your project. The onus is on the person adding the complexity to rationalize it. If there is no rationale, it should probably be removed.

Reviewing Go Code

Code Review Comments has a lot of information on what to look for and tolerate in code.