Capstone · Go Programming (backend and cloud)
Capstone: an appointment API for a clinic
The brief
Aarogya Clinic, a small multi-doctor clinic in Pune, books patients by phone and a paper register, and double bookings happen every week. You build its appointment API as a portfolio piece: config from the environment, validated bookings with clear 400 errors, PostgreSQL with a constraint that makes double booking impossible, request IDs and JSON logs, tests that pass with -race, a small Docker image, docker compose, graceful shutdown and a README.
Why it matters
Clinics, salons, coaching centres and service companies all need booking APIs, and this one has every part an interviewer checks in a Go backend repository: a clean package layout, validation, SQL that is safe and correct under concurrency, errors mapped to status codes, structured logs, tests, a container and documentation. Being able to explain why the database (not Go code) prevents double booking is a strong interview answer.
Skills you practise
- config from environment variables
- domain validation with table-driven tests
- PostgreSQL with pgx and database/sql
- unique and partial indexes, errors.As with *pgconn.PgError
- middleware: request IDs, slog JSON logs, panic recovery
- httptest with a fake store, -race and -cover
- multi-stage Docker image and docker compose
- graceful shutdown on SIGTERM
- README and CI
You need
- Go 1.22 or newer installed from go.dev/dl
- Docker Desktop (or Docker Engine with the compose plugin)
- Git Bash or WSL on Windows for the curl and docker commands (PowerShell quoting and < redirection differ)
- A GitHub account, to publish the repository with its CI (optional but recommended)
What you will have at the end
A public Git repository: a production-style Go appointment API (example.com/clinic) with PostgreSQL, validation, request IDs and JSON logs, tests that pass with -race, a small Docker image, docker compose, graceful shutdown, CI and a README.
How it is marked (rubric, 100 points)
| Working APIEvery endpoint gives the right status and JSON; validation lists all problems; double bookings are impossible; phones are masked. | 30 |
|---|---|
| Production readinessConfig from env with fail-fast, request IDs and JSON logs, panic recovery, /healthz and /readyz, graceful shutdown, a small non-root image. | 25 |
| Code quality and testsClear package layout (clinic, store, httpapi), handlers depend on an interface, table-driven and httptest tests pass with -race, vet clean. | 25 |
| Documentation and explanationA README with one-command start, curl examples and design decisions, and you can explain every choice in an interview. | 20 |
0/12 steps done
Step 1 of 12
Configuration that fails fast
TestLoad passes, and go run . without DATABASE_URL logs a JSON error and exits with status 1.
Run go mod init example.com/clinic and create every file from the tabs at its path. The same binary will run on your laptop, in CI and in a container; only environment variables change. config.Load uses defaults for optional settings (PORT 8080, LOG_LEVEL info) and returns an error for the required DATABASE_URL, so a misconfigured deploy stops at once with a clear message, not at the first query. main logs with slog's JSON handler, which log platforms can search by field.
$ mkdir clinic && cd clinic
$ go mod init example.com/clinic
go: creating new go.mod: module example.com/clinic$ unset DATABASE_URL; go test ./internal/config/; go run .Your notes: main.go, internal/config/config.go, internal/clinic/clinic.go, internal/store/postgres.go, internal/httpapi/api.go, internal/httpapi/middleware.go, Dockerfile, README.md
Write down each command you ran. It goes into your project summary.