DEV Community

Cover image for Go - Project Structure and Guidelines
Ankit Kumar
Ankit Kumar

Posted on

Go - Project Structure and Guidelines

Alt Text

Assuming you read my post you should have the starting point for a minimal go web service. For your first project it is easier to keep all your code in one folder, in the base of your project, but at some point you want to restructure things.

Packages
All go code is organised into packages and its simply consists of several .go files. A package is the entry point to access Go code.

  1. Best Practice to use multiple files
    a. Feel free to separate you code into as many files as possible.
    b. Aim to ensure it is easy to navigate your way around
    c. Loosely couple sections of the service or application

  2. Keep types close
    It is often a good practice to keep the core types grouped at the top of a file.

  3. Organise by responsibility
    In other languages we organise types by models or types but in go we organise code by their functional responsibilities.

  4. Start to Use Godoc
    Godoc extracts and generates documentation for Go programs. It runs as a web server and presents the documentation as a web page.

  5. Dont't write your business logic to main.go

Naming Convention

  1. Package names should be lowercase. Don't use snake_case or camelCase.
  2. Avoid overly use terms like util, common, script etc
  3. Use singular form
  4. Rename should follow the same rules

 (
    gourl "net/url"
    myurl "myApp/url"
)

Enter fullscreen mode Exit fullscreen mode

*Repository Structures examples: *

```fooApp/


  circle.yml
  Dockerfile
  cmd/
    foosrv/
      main.go
    foocli/
      main.go
  pkg/
    fs/
      fs.go
      fs_test.go
      mock.go
      mock_test.go
    merge/
      merge.go
      merge_test.go
    api/
      api.go
      api_test.go


```

As you noticed, there is func_test.go file in the same directory. In Go, you save unit tests inside separate files with a filename ending with _test.go. Go provides go test command out of the box which executes these files and runs tests.

Common terms we use in package structure

  1. /cmd
    This folder contains the main application entry point files for the project, with the directory name matching the name for the binary.

  2. /pkg
    This folder contains code which is OK for other services to consume, this may include API clients, or utility functions which may be handy for other projects but don’t justify their own project.

  3. /internal
    This package holds the private library code used in your service, it is specific to the function of the service and not shared with other services.

  4. go.mod
    The go. mod file defines the module's module path, which is also the import path used for the root directory, and its dependency requirements, which are the other modules needed for a successful build.

  5. go.sum contains all the dependency check sums, and is managed by the go tools. The checksum present in go.sum file is used to validate the checksum of each of direct and indirect dependency to confirm that none of them has been modified.

e.g.

```


├── LICENSE
├── README.md
├── config.go
├── go.mod
├── go.sum
├── clientlib
│   ├── lib.go
│   └── lib_test.go
├── cmd
│   ├── modlib-client
│   │   └── main.go
│   └── modlib-server
│       └── main.go
├── internal
│   └── auth
│       ├── auth.go
│       └── auth_test.go
└── serverlib
    └── lib.go


```

Thanks!!

Top comments (3)

Collapse
 
oglex85 profile image
DanyQuery

can you show me the github repository, i wanna see the code

Collapse
 
axelrhd profile image
AxelRHD

How is this working with the go run / go build commands? I always got errors. Do I have to change the working directory?

Collapse
 
huholoman profile image
Huholoman • Edited

Your "main.go" files are under cmd. You can make multiple binaries from one project, for example you can have (rest) server which presents app api using rest api interface and then you can have cli, which presents app api using cli interface.

main.go file must be in "main" package to make it buildable/runnable and you can have only one "main" func per package. That means you have to wrap your main.go file to its own folder, so the file struct is

cmd/
    server/
        main.go
    cli/
        main.go
Enter fullscreen mode Exit fullscreen mode

These main.go files just assemble the code together, otherwise your code should be in internal or pkg dirs if you follow the most popular (but not official) project structure.

Now you can run or build any of it by running go run cmd/server or gor run cmd/main.

Now Im not sure, but I think you should name folder and package the same - which we are not doing here in the cmd example, but this nasty hack makes possible to keep multiple main.go files in one place. You could put your main.go in /cmd/(server|cli)/main/main.go tho, but i havent seen this, not a signle once.