A full-featured, production-ready, containerized microservice template for building applications in Go. Includes a demo Users microservice exposing a REST API, providing typical functionality to operate on the resource backed by a SQL database.
View the API's OpenAPI Documentation here
Fork this project to start building your own REST-based microservice application.
- Local Go installation, ideally the same version in
go.mod
- Alternatively can run the program in Docker
- GNU make for running Makefile commands
- Docker, likely Docker Desktop for OSX and Windows users
- VSCode, not required but when advantageous its features to enhance developer experience are leveraged
- Kubernetes, again not required but this is the technology of choice for deploying
Fetch Go dependencies
make init
Compile the Go application
make build
Start the database
make start-db
Run the microservice app directly
make run
Execute unit tests
make test
Stop the database
make stop-db
Get help with all make commands
make help
Query the application using Curl:
curl -X POST http://localhost/users/Bruce
curl http://localhost/users/1
Run the microservice app in Docker
make d-build
make d-start
stop the app
make stop
Rebuild
docker rm users
make d-build
make d-start
Precondition: kubectl is installed in your local environment, and connected to a Kubernetes cluster.
First deploy the database:
kubectl apply -f service.postgres.yaml
Next deploy the Users service:
kubectl apply -f service.users.yaml
Tail application logs:
kubectl logs -f users
The service is exposed externally with a Kubernetes object called a NodePort Service. This NodePort is exposed externally on port 30080
. If you're using a local K8s cluster like MiniKube or Docker Desktop, it will be accessible via localhost
, or 127.0.0.1
:
curl http://localhost:30080/v1/users/1
The Postgres database is exposed internally only, because in a real world scenario it should not be accessible from outside the Kubernetes cluster. Assuming your cluster is running locally, you can connect to it by telling Kubernetes to expose the connection:
kubectl port-forward postgres 5432
Then connect to it as you normally would, e.g.:
psql -U microservice
Delete application resources created on the cluster:
kubectl delete service postgres users
kubectl delete pod postgres users
Here's how the architecture within Kuberenetes looks:
- REST API for integrating with other services
- A simple Users service implementing Create, Read, Update, Delete operations on a User resource
- This simple, generic service acts as a template from which other services can be built
- Go 3rd Party Packages
- Echo web framework
- GORM ORM Library
- Validator package for easy validation of input parameters
- Testify Assert and Mock packages for more convenient unit testing
- golangci-lint, a popular linter for the Go language
- Configured with
.golangci.yml
config - VSCode Integration configured via
.vscode/settings.json
- Configured with
- PostgreSQL database
- Database schema managed with GORM Auto-migration
- Makefile for ease of operation
- Encapsulates commands to build, run, test, clean, etc, the project
- VSCode Integration
launch.json
configurations for:- Debugging native application
- Debugging in Docker container using Delve debugger
settings.json
configuring VSCode to use golangci-lint
- GitHub Integrations
- GitHub Actions to run build & tests
- OpenAPI doc hosted with GitHub Pages
- Workflow Status Badge showing CI build status
- Docs
- README.md
- OpenAPI definition documenting REST API, hosted with GitHub Pages
- CI configured using GitHub Actions
- This validates changes on every push by building & testing the source code
- Docker for containerizing the application
- A minimalist base image,
gcr.io/distroless/base-debian10
, is used to keep the build image small - Push the image using Docker's public image library. A free Docker account is required.
- A minimalist base image,
- Kubernetes for deploying the containerized application
- Objects are defined in Kubernetes manifest files
To run your changes in Kubernetes follow these steps:
- Log in to Docker
docker login -U username
-
Set
DOCKER_USERNAME
inMakefile
to your Docker username -
Build and tag the Docker image
make d-build
- Push the Docker image to
make d-push
- Deploy to Kubernetes with the instructions under "Running in Kubernetes" above
Update a mock with the following command, e.g. for the repository.Repository
interface:
cd repository/
mockery --name Repository --inpackage --outpkg=mock_Repository.go
The Users API is documented with OpenAPI. The OpenAPI document is located at docs/openapi.yaml.
There are tools for automating the creation of an OpenAPI document for an API. The document for this API is updated manually at this time.
A human-readable rendering is hosted with GitHub pages at github.com/bruc3mackenzi3/go-microservice-template. This is enabled in the GitHub repository settings.
For more information on working with OpenAPI, see the official documentation.
For more information on GitHub Pages, see this getting started page.
- BUG: Docker app cannot connect to DB - likely needs a Docker network configured
- Update OpenAPI yaml
- Better document API calls
- Embed CURL commands in README
- Add Postman Collection
- GitHub integrations
- CI build with GitHub Actions
- Add Go lint step to CI. Additional steps?
- Integration tests
- Test line coverage report
- PR workflow
- Require PR for main merge?
- Block PR merge on CICD passing
- CI build with GitHub Actions
- Replace env variables in Makefile with .env file
- API endpoint implementing pagination
- Inter-service communication e.g. with gRPC
- Logging
- Context