This is a template repository that provides boilerplate code for a service written in Go.
Supported data stores
- Kafka
- MongoDB
- MySQL
- NATS
- PostgreSQL
- Redis
Supported deployment methods
- Kubenretes via Helm
| Directory path | Description |
|---|---|
/.data |
Persistent data storage |
/bin |
Contains built binaries |
/cmd |
Contains command entrypoints |
/deploy |
Contains deployment manifests |
/internal |
Contains app-related packages |
-> ./api |
Contains HTTP-related packages and defines mainly routing |
-> ./constants |
Contains build configurations and app-wide constants |
-> ./database |
Contains database connection management code |
-> ./docs |
Contains Swagger documentation |
-> ./example |
Contains an example endpoint that connects to the HTTP API |
-> ./server |
Contains the server instance code |
/tests |
Contains test artifacts |
/vendor |
Contains dependenices |
To test the CLI you can run go run ./cmd/app, help information should be available.
The following commands are included in the boilerplate which you can remove if not applicable to your project:
app debug kafka- tests the connection to Kafka (runmake kafka-jksandmake start-kafkabefore this)app debug mongo- tests the connection to MongoDB (runmake start-mongobefore this)app debug mysql- tests the connection to MySQL (runmake start-mysqlbefore this)app debug nats- tests the connection to NATS (runmake start-natsbefore this)app debug postgres- tests the connection to PostgreSQL (runmake start-postgresbefore this)app debug redis- tests the connection to Redis (runmake start-redisbefore this)app start job- sample command to start a one-time jobapp start server- sample command to start the serverapp start worker- sample command to start a worker service
cobrafor structuring the app's CLI invocations and flags configurationviperfor managing configuration on a service levelgofiberfor the HTTP server and HTTP API scaffoldingswaggoto generate Swagger documentation
- Docker for build/release packaging
- Docker Compose for bringing up development services
- KinD for bringing up a local Kubernetes cluster
nkfor generating NATS nkeys- Make for development operations recipes
- Kafka
- NATS for queueing/message brokering
- MySQL for RDBMS usage
- PostgreSQL for RDBMS usage
- MongoDB for NoSQL usage
- Redis for caching
This repository uses Makefile for storing development operations. Included operations are:
make binarybuilds the binary and stores it in./bin/make deploy-kinddeploys the application onto a local Kubernetes clustermake deploy-k8sdeploys the application onto the currently selected Kubernetes clustermake depspulls in the dependencies into./vendor/make docsgenerates all documentationmake docs-swaggogenerates just the Swagger documentation usingswaggomake imagebuilds the Docker imagemake install-swaggoinstallsswaggoat the latest versionmake kafka-jksgenerates the keys and certificates required for Kafka securitymake kind-loadloads the image into the local Kubernetes clustermake nats-nkeycreates a new nkey for use with NATSmake publish-imagepublishes the image in it's current form using a concatenation of${GIT_BRANCH}and${GIT_COMMIT_SHA}separated by a-as the image tagmake startstarts the HTTP server using defaultsmake start-kafkastarts a local Kafka instance via Docker Composemake start-kindstarts a local Kubernetes cluster with KinDmake start-mongostarts a local MongoDB instancemake start-mysqlstarts a local MySQL instancemake start-natsstarts a local NATS instancemake start-postgresstarts a local PostgreSQL instancemake start-redisstarts a local Redis instancemake testruns tests on the application and produces coverage artifacts at./tests/
To configure the Makefile recipes, create a new Makefile.properties in the root of this repository. Configurable values can be found in the Makefile above the line -include Makefile.properties.
Some common configurations are documented below. Insert the code snippets into Makefile.properties.
See the ./Makefile for full details
Sample connection code with test pings can be found in ./cmd/app/commands/debug.
All database packages at ./internal/database expose the global interface:
Db(name ...string): Use this to retrieve a database connection. Ifnameis specified, the named connection will be returned.Init(opts database.ConnectionOpts, name ...string): Use this to initialise a database connection. Ifnameis specified, a named connection will be created and added to a map of connections which you can retrieve usingDb(connectionName).Close(name ...string): Use this to close connections you no longer need. Ifnameis specified, a named connection will be closed and removed from the connection map. You need to call this before youInit()another connection with the same name.
Named connections can be used to implement logical tenant separations at the connection level. For example for B2B businesses where each tenant has a separate database instance, a new connection for tenantA can be initialised using Init(opts, "tenantA") and retrieved using Db("tenantA").
Insert the following into Makefile.properties:
APP_NAME := "app2"You will also need to:
- Rename the module in
go.modtoapp2and rungo mod vendor - Rename the chart in
./deploy/charts/app/Chart.yamltoapp2 - Rename the directory
./deploy/charts/appto./deploy/charts/app2 - Rename the directory in
./cmd/appto./cmd/app2
Insert the following into Makefile.properties:
IMAGE_REGISTRY := "docker.registry.domain.com"
IMAGE_PATH := "your-org/your-app"
IMAGE_TAG := "main-123456"This example will cause images to be tagged and pushed to docker.registry.domain.com/your-org/your-app:main-123456
Domains should be in their own internal package in ./internal/. A package should contain both the controllers and the HTTP interfaces exposed with a reference performed in ./internal/api/
An example with both controllers and HTTP interfaces can be found in ./internal/example for an example domain.
This repository being a boilerplate contains some redunancies like database code which might not be used depending on your service. Before going to production:
- Helm chart is name appropriately
- Service is named appropriately
- Remove the
./cmd/app/commands/debug/*directories that aren't used. Eg if MongoDB is not used, remove./cmd/app/commands/debug/mongoand remove the reference to it in./cmd/app/commands/debug/debug.go. This way, code for handling that database type will not be included in your binary. - Disable Swagger in production (unless you want it in production)
- Generate fresh keys on a privileged system and delete any keys that come with the boilerplate
See ./LICENSE. Basically, do whatever you want with this.