A recipe detail response had to combine ingredients, translations, substitutes, and sauces into one screen-shaped result.
The query needed locale fallback, and the columns and joins differed by use case. A table-centered abstraction alone would make the actual read intent harder to review.
I chose pgx and sqlc instead of an ORM: each use case keeps its SQL explicit, while generated types preserve type safety in application code. The point was not that an ORM is always worse, but that this service benefited from reviewing query shape directly.
- Kept recipe detail, translation, and substitute reads as use-case-specific SQL.
- Used sqlc-generated code to keep query result types explicit.
- Made locale fallback and conditional relation reads visible in SQL.
The Go API implements reads for recipes, ingredients, translations, and substitutes with query-level visibility into their relationships. I did not measure a speed comparison with an ORM or quantify N+1 improvements.
I learned that a technology choice should explain where data shape is reviewed and which invariants are protected, not only name the libraries used.