liveBook · Manning

Cmd directory pattern

As explained in Go in Action, Second Edition

The cmd directory pattern organizes independently executable Go programs into separate subdirectories within a module.

When related Go programs share libraries, putting each executable in its own cmd subdirectory keeps entry points distinct without separating the shared code. Each executable has a main package and main() function, such as cmd/api/main.go. This is a convention, not a required Go project layout. section 11.1.1 section 11.3.2

Keep the command focused on starting the program:

  • Place startup code in cmd/api/main.go: initialize storage, construct handlers, register routes, and start the HTTP server. section 11.3.2
  • Keep HTTP handlers in internal/handlers when they are used only by the API module; import the shared storage module rather than creating another store package. section 11.3.2
api/
├── cmd/
│   └── api/
│       └── main.go         #1
├── internal/
│   └── handlers/
│       ├── handlers.go      #2
│       └── handlers_test.go
└── go.mod

The directory tree shows the command entry point alongside, rather than mixed with, the API module’s internal handlers. section 11.3.2

package main

import (
    "fmt"
    "log"
    "net/http"

    "github.com/YOUR_USERNAME/go-news/api/internal/handlers"
    "github.com/YOUR_USERNAME/go-news/storage"
)

func main() {
    store, err := storage.NewBoltStore("./articles.db", true) #1
    if err != nil {
        log.Fatalf("failed to initialize storage: %v", err)
    }
    defer store.Close() #2

    h := handlers.New(store) #3

    mux := http.NewServeMux() #4
    h.RegisterRoutes(mux)

    fmt.Println("Starting API server on :8080")
    if err := http.ListenAndServe(":8080", mux); err != nil { #5
        log.Fatal(err)
    }
}

The main function shows the command wiring a shared store into handlers and starting the server. section 11.3.2

How Go in Action, Second Edition covers it

How deep it goes
Defines the directory convention and shows an API entry point with service startup code.
Examples
Shows cmd/api/main.go starting an HTTP server and an API directory tree with separate internal handlers.
What you can do after
Build it from scratch: place an executable entry point in its own cmd subdirectory and wire it to shared components.
How it connects
Connects Go modules, main packages, internal packages, dependency injection, and shared storage modules.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Go in Action, Second Edition. The section links point to the parts of the book it draws on.