MiniCart

Stage 00 - Setup

What you'll build

The service

MiniMart is an HTTP API with two domains - a product catalog and an order system - and six endpoints:

MethodPathPurpose
GET/healthLiveness check
POST/v1/productsAdd a product
GET/v1/productsList products
GET/v1/products/{id}Fetch a product
POST/v1/ordersPlace an order
GET/v1/orders/{id}Fetch an order

You build it with the standard library first (stages 01-10), then give it real Postgres, Kafka, and Docker (stages 11-14).

Those tools are not the architecture. Go, Postgres, Kafka, Docker, or even microservices can still produce a system that is painful to change. The point of MiniMart is the habit underneath them: keep business decisions in one place, keep technology at the edges, and make every boundary explicit enough that a future change has somewhere obvious to land.

The rule

Every decision in this course follows from one rule:

Source-code dependencies point inward. presentation → application → domain. Infrastructure implements interfaces the domain defines; the domain never imports infrastructure.

The four layers, and who is allowed to import whom:

Code
presentation/     input adapters   - HTTP handlers, Kafka consumers
      │ imports
      ▼
application/      use cases        - orchestration
      │ imports
      ▼
domain/           entities + ports - the core; defines the interfaces
      ▲
      │ implements the ports
infrastructure/   output adapters  - Postgres, Kafka producer

The domain sits in the centre and depends on nothing outward. That is what lets you test business rules without a database, and swap Postgres for anything else without touching business code. You'll prove both claims later.

Toolbox & working copy

Four tools carry the course:

  • Go 1.22+ - the language. 1.22 is the floor because routes use method-aware patterns like GET /v1/products/{id}.
  • Docker + Compose - runs Postgres and the Kafka broker locally from stage 11.
  • sqlc - turns plain SQL into type-safe Go (stage 11).
  • dbmate - runs versioned SQL migrations (stage 11).

You install sqlc and dbmate now so later stages don't stall on setup.

Check Go and Docker:

Shell
go version      # go1.22 or newer
docker version  # client + server both respond

Install the two extra CLIs (they land in $(go env GOPATH)/bin - make sure that's on your PATH):

Shell
go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest
go install github.com/amacneil/dbmate/v2@latest
sqlc version
dbmate --version

Create your working copy. Make a fresh module in a directory you'll work in:

Shell
mkdir -p ~/minimart
cd ~/minimart
go mod init minimart
go build ./...

go build ./... should print nothing and exit 0. The module is just a go.mod so far; you write everything else.

For this course: @latest keeps setup short. A team project should pin exact tool versions in its Makefile and CI so every developer generates identical code.

Verify

Shell
go version && docker version && sqlc version && dbmate --version && \
  (cd ~/minimart && go build ./... && echo "module builds")

All four version lines print, and you see module builds.

Practice & reflection

Exercise

In the layer diagram, why is the arrow from infrastructure/ pointing up into domain/, the opposite direction from the others?

Answer

Because infrastructure implements an interface the domain owns. The domain declares a Repository interface (a "port"); the Postgres code depends on that interface to satisfy it. The dependency points toward the domain, like every other arrow - the domain still imports nothing outward.

Toolbox & working copy

Exercise

Why does this section create a fresh Go module instead of starting from a prebuilt starter project?

Answer

Because the first step is taking control of the working copy. A fresh module gives you a known starting point, proves the toolchain works on your machine, and makes every file that appears later something you intentionally added.