How small interfaces, ports/adapters, and constructors show up in real backend Go design.
Your win: explain the architecture patterns in this repo using Go terms the rest of the course has already built up: consumer-defined interfaces, ports/adapters, composition roots, and transport boundaries.
In plain English
Senior backend Go design is mostly about keeping decisions local: transport at the edge, business rules in plain packages, infrastructure behind narrow seams, and wiring concentrated in constructors or bootstrap code.
Why this lesson belongs in a Go course
At first glance, architecture can look “bigger” than language learning. But in Go, architecture is where the language's preferences become visible: small interfaces, explicit wiring, concrete types by default, and very boring boundaries that stay readable under scale.
The four boundaries to notice
Controllers
Thin transport adapters: gRPC, HTTP, Kafka.
Application / service
Use-case orchestration and business flow.
Ports
Interfaces describing what the application needs.
Adapters
Concrete repos or clients implementing those ports.
Repo anchor
Your codebase already teaches this well: spike and notification modules show CQRS / hexagonal seams, conversationmgmt shows core/port separation, and bootstrap code acts as the composition root that wires concrete implementations into small interfaces.
Why senior Go likes small interfaces
Tests can replace collaborators cheaply
Infrastructure details do not leak into business logic
Callers define exactly the behaviour they need
Swapping implementations changes wiring, not domain flow
Senior framing
In Go, dependency inversion often looks almost boring: define a tiny interface where it is consumed, provide a constructor, and keep request/transport-specific details at the edge. That boredom is a strength.
Common mistake
Creating giant shared interfaces in “common” packages before a real seam exists. That usually increases coupling instead of reducing it, and it makes testing and refactoring harder.
Read this next
Effective Go + your repo map
The language sources explain the philosophy. Your own repo shows how that philosophy lands in transport boundaries, constructors, and thin adapters.
Q1. In idiomatic Go architecture, interfaces are usually defined…
Consumer-owned interfaces keep seams small and purposeful.
Q2. The transport boundary should usually own…
Keep transport concerns at the edge so the inner layers stay reusable.
What does dependency inversion look like in Go without a framework?
recall, then click to reveal
A small interface defined by the caller, a concrete adapter implementing it, and constructor/bootstrap code wiring the concrete value into the higher-level service.
Want me to map one real service in this repo into controller → application → port → adapter form? Ask me.