
Go Interfaces Are Ports: The Language Feature That Makes Clean Architecture Free
The biggest insight that changed how I structure Go services: Define interfaces where you USE them, not where you implement them. This one idea — consumer-defined interfaces — is what makes hexagonal architecture feel native in Go instead of bolted on. The Java Way vs The Go Way In Java, the class that implements an interface must explicitly declare it: public class PostgresOrderRepository implements OrderRepository { // Must import OrderRepository. Must name it. Coupled at the declaration. } In Go, a type satisfies an interface just by having the right methods. No keyword. No import. // Domain package defines what it needs type OrderRepository interface { Save ( ctx context . Context , order Order ) error FindByID ( ctx context . Context , id string ) ( Order , error ) } // Adapter package — doesn't even need to know the interface exists type PostgresOrderRepository struct { db * sql . DB } func ( r * PostgresOrderRepository ) Save ( ctx context . Context , order Order ) error { // SQ
Continue reading on Dev.to
Opens in a new tab


