"ToDo API" Microservice Example
This is an educational repository that includes a microservice written in Go. It is used as the principal example of my video series: Building Microservices in Go.
It's a collection of patterns and guidelines I've successfully used to deliver enterprise microservices when using Go.
The whole purpose of this project is to give you an idea about structuring your Go project with 3 principal goals:
- It is enterprise, meant to last for years,
- It allows a team to collaborate efficiently with little friction, and
- It is as idiomatic as possible.
Join the fun at https://youtube.com/MarioCarrion.
Domain Driven Design
This project uses a lot of the ideas introduced by Eric Evans in his book Domain Driven Design, I do encourage reading that book but before I think reading Domain-Driven Design Distilled makes more sense, also there's a free to download DDD Reference available as well.
On YouTube I created a playlist that includes some of my favorite talks and webinars, feel free to explore that as well.
Talking specifically about microservices only, the structure I like to recommended is the following, everything using
> depends on the domain being implemented and the bounded context being defined.
build/: defines the code used for creating infrastructure.
: define concrete cloud provider.
: contains a Dockerfile used for building the binary.
: uses primary database.
: uses readonly databases.
migrations/: contains database migrations.
seeds/: contains file meant to populate basic database values.
internal/: defines the core domain.
: a concrete repository used by the domain, for example
http/: defines HTTP Handlers.
service/: orchestrates use cases and manages transactions.
pkg/public API meant to be imported by other Go package.
There are cases where requiring a new bounded context is needed, in those cases the recommendation would be to define a package like
internal/ that then should follow the same structure, for example:
go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/[email protected] go install github.com/kyleconroy/sqlc/cmd/[email protected] go install github.com/maxbrunsfeld/counterfeiter/[email protected] go install github.com/deepmap/oapi-codegen/cmd/[email protected]
In no particular order:
- Database migrations
- Repository Pattern
- Project Layout
- Dependency Injection
- Secure Configuration
- OpenAPI 3 and Swagger-UI
- Infrastructure as code
- Metrics, Traces and Logging using OpenTelemetry
- Error Handling
- Persistent Storage (using PostgreSQL)
- REST APIs
- Containerization using Docker
- Whatever else I forgot to include
- 2016: Peter Bourgon's: Repository structure
- 2016: Ben Johnson's: Standard Package Layout
- 2017: William Kennedy's: Design Philosophy On Packaging
- 2017: Jaana Dogan's: Style guideline for Go packages
- 2018: Kat Zien - How Do You Structure Your Go Apps
Please notice in order to run this project locally you need to run a few programs in advance, if you use Docker please refer to the concrete instructions in
docs/ for more details.
There's also a docker-compose.yml, covered in Building Microservices In Go: Containerization with Docker, however like I mentioned in the video you have to execute
docker-compose in three steps:
docker-compose up, here the api service will fail because the
postgresservice takes longer to start.
docker-compose up api, api will successfully start however interacting with it will fail because the database migrations are missing.
docker-compose run api migrate -path /api/migrations/ -database postgres://user:password@postgres:5432/dbname?sslmode=disable upto finally have everything working correctly.