Table of Contents
- Bookstore REST API
- Overview
- Architecture
- Tech Stack
- Getting Started
- API
- Project Layout
- Testing Strategy
- Lessons Learned
- Future Improvements
- 🎒 Portfolio
Bookstore REST API¶
A production-shaped CRUD REST API in Go — the Month 4 (web + databases) project.
Overview¶
A REST API for managing authors and books, built with idiomatic net/http + chi, persisted in PostgreSQL via pgx, with versioned migrations, request validation, structured logging, and a clean layered architecture (handler → service → repository). Full brief in SPEC.md.
⚠️ This is its own Go module (it needs third-party libraries and a running database). It is intentionally excluded from the repo's root CI. To build/run it:
go mod tidy+ a Postgres instance.
Architecture¶
flowchart LR
client[Client] -->|HTTP/JSON| R[chi router + middleware]
R --> H[handler]
H --> S[service<br/>business rules + validation]
S --> Repo[repository interface]
Repo --> PG[(PostgreSQL via pgx)]
Dependencies point inward: handlers know HTTP, repositories know SQL, and the service in the middle knows neither — only domain models and the repository interface.
Tech Stack¶
Go · chi (routing/middleware) · pgx (Postgres) · golang-migrate (migrations) · log/slog (logging) · httptest + table-driven tests · Docker
Getting Started¶
cd projects/03-rest-api-bookstore
cp .env.example .env # set DATABASE_URL etc.
go mod tidy # resolve dependencies
# start Postgres (example)
docker run --rm -d --name bookstore-db -e POSTGRES_PASSWORD=postgres -p 5432:5432 postgres:16
make migrate-up # apply migrations/
make run # or: go run ./cmd/api
API¶
| Method | Path | Description |
|---|---|---|
| GET | /healthz |
liveness |
| GET | /v1/books |
list (pagination/filter) |
| POST | /v1/books |
create |
| GET | /v1/books/{id} |
fetch one |
| PUT | /v1/books/{id} |
update |
| DELETE | /v1/books/{id} |
delete |
| GET/POST | /v1/authors … |
authors CRUD |
Project Layout¶
cmd/api/ composition root + graceful shutdown
internal/book/ handler, service, repository, model
internal/author/ handler, service, repository, model
internal/middleware/ request logging, recovery, request IDs
internal/httperr/ consistent JSON error responses
internal/validate/ input validation
internal/platform/postgres/ connection pool + migrations
internal/config/ env-driven configuration
migrations/ golang-migrate SQL (up/down)
db/queries/ SQL (sqlc-style)
Testing Strategy¶
Table-driven unit tests for services (against a fake repository) and handlers (httptest). Integration tests run against a real Postgres via testcontainers-go (require Docker) — see SPEC.
Lessons Learned¶
- Where to put validation (service vs handler) and how to map domain errors → HTTP status codes consistently.
- Connection-pool sizing and threading
contextdeadlines into every query.
Future Improvements¶
- sqlc-generated queries; OpenAPI spec; JWT auth; cursor pagination; rate limiting.
🎒 Portfolio¶
Résumé bullets:
- "Designed and shipped a layered REST API in Go (chi, pgx, PostgreSQL, golang-migrate) with request validation, structured logging, consistent error handling, and httptest + testcontainers tests."
Interview talking points: layered/hexagonal boundaries; repository pattern + interface seams for testing; migrations strategy; mapping domain errors to status codes; pool tuning.
⬅ Projects · Repo README