Writing an API project in Golang can be likened to art, due to the absence of a de facto framework or established standards for development. There is a plethora of approaches available, and it isn't uncommon to discover that the chosen method isn't as effective or extensible as initially assumed.
In this project, I aim to explore and demonstrate the outcomes of several such approaches:
- Logging with
zap
: A fast, structured, leveled logging in Go. - Metrics with
otel
(OpenTelemetry): Instrumenting code to collect and report metrics. - Tracing with
otel
(OpenTelemetry): Capturing the flow and latency of operations in our application. - Dependency Injection using
fx
: A framework for dependency injection providing a robust way of managing dependencies. - Migrations using
atlasgo
: Managing database schema migrations in an agile manner.
I am following the rules defined by golang-standard.
The internal/domain
package contains the domain-specific logics. As rule of thumbs everything defined in
internal/domain
must use only go standard packages or other application packages, so they should not use any third party
libraries directly.
The infrastructure layer does the actual using of third party libraries and resides in infra
package.
Actual implementation always goes into the infra
package.
To facilitate database access, we've defined repository interfaces within the domain
package.
These form the contract for our data access methods.
Corresponding implementations can be found in the infra
package,
ensuring a separation of concerns between our domain definitions and infrastructure-specific code.
- The interfaces are prefixed with
repo
to denote their role as repositories within the domain layer.
- The actual implementations carry a
db
prefix, indicating their direct interaction with the database and their role within the infrastructure layer.