How to organize Go code with packages?
For small programs, you probably don’t need to define another package other than the special package: main. For bigger programs, you might need to define your own packages to organize your code. For people who work on the same code to create many programs, they may need to define their own libraries and import these to their own programs.
In my own projects, I create a cmd folder to keep entry-point applications of my program, then I do dependency-injection and other orchestration code there. All of the other code lives inside internal folders and not get reused by the outer packages other than the ones in my program.
Splitting packages into sub-directories
You can split packages into subdirectories, Go stdlib uses this style. Look at http package for example. It’s inside net package. Http things belong to network things, so, they put it under net package. However, that doesn’t mean that, http package can use net package’s internals, it cannot. Each go package is a different beast on its own, there’s no relationship between net and http package in stdlib other than the organization purposes.
Go provides no sub-packaging mechanism and when you split up your packages to organize your BIG package, you may make some of the internals of your package to the outside world, and so, anyone can import them. You may not want this, so, internal package convention prevents your packages to be imported from unwanted parties. I explain internal packages here in this post.
And, last, new gophers who are beginning to Go, create, src/ folders, you don’t need to do that. Just put your source files into your project root. It’s better that way.
- Names should be as simple as possible like: http, zip, and time. You and other people are going to use and recall them with this name. Keep them short, simple, concise and to the point.
- Do not use double or more words in names like: net_http. Do it like: net/http. Different packages, but because http package is inside net directory, if there was another package which named also as http, there will be no problem, because they live in separate directories.
- Let the package path speaks for what the packages does. net/http. It’s clear, isn’t? http package is a package that does things related somehow with networking. If it was inside security/http package it’d imply different meanings.
- Use common abbrevations if it’s familiar to the programmers (or to the programmers in domain of the application you’re building). For example: Instead of formattedIO, stdlib uses fmt.
- Definitely avoid ultra-generic package names like api, models, common, utils, helper etc. For example: Instead of a model package, define a package that does user things named as user.
- Do not use underscores or camel-casing. Just use lowercase letters.
- Names can contain unicode characters (however I don’t recommend using this)
- There is no package versioning in Go. go get always fetches from HEAD from a git repository. However, there are some workarounds. For example: You can save a package you want manually into your program, so that you can use whatever version you want. More tips here.
- To get all of the dependencies for the current package you’re working in by typing: go get ./…
You made it here! Thanks for reading! And please support me: Follow my publication. and add claps to my post! Encourage me to write more.
I’m mostly tweeting about Go, you can follow me on twitter: @inancgumus.
You will receive Go tips, tutorials and notifications about my upcoming online Go course.
Originally published at blog.learngoprogramming.com on September 26, 2017.