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-jks
andmake start-kafka
before this)app debug mongo
- tests the connection to MongoDB (runmake start-mongo
before this)app debug mysql
- tests the connection to MySQL (runmake start-mysql
before this)app debug nats
- tests the connection to NATS (runmake start-nats
before this)app debug postgres
- tests the connection to PostgreSQL (runmake start-postgres
before this)app debug redis
- tests the connection to Redis (runmake start-redis
before 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
cobra
for structuring the app's CLI invocations and flags configurationviper
for managing configuration on a service levelgofiber
for the HTTP server and HTTP API scaffoldingswaggo
to generate Swagger documentation
- Docker for build/release packaging
- Docker Compose for bringing up development services
- KinD for bringing up a local Kubernetes cluster
nk
for 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 binary
builds the binary and stores it in./bin/
make deploy-kind
deploys the application onto a local Kubernetes clustermake deploy-k8s
deploys the application onto the currently selected Kubernetes clustermake deps
pulls in the dependencies into./vendor/
make docs
generates all documentationmake docs-swaggo
generates just the Swagger documentation usingswaggo
make image
builds the Docker imagemake install-swaggo
installsswaggo
at the latest versionmake kafka-jks
generates the keys and certificates required for Kafka securitymake kind-load
loads the image into the local Kubernetes clustermake nats-nkey
creates a new nkey for use with NATSmake publish-image
publishes the image in it's current form using a concatenation of${GIT_BRANCH}
and${GIT_COMMIT_SHA}
separated by a-
as the image tagmake start
starts the HTTP server using defaultsmake start-kafka
starts a local Kafka instance via Docker Composemake start-kind
starts a local Kubernetes cluster with KinDmake start-mongo
starts a local MongoDB instancemake start-mysql
starts a local MySQL instancemake start-nats
starts a local NATS instancemake start-postgres
starts a local PostgreSQL instancemake start-redis
starts a local Redis instancemake test
runs 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. Ifname
is specified, the named connection will be returned.Init(opts database.ConnectionOpts, name ...string)
: Use this to initialise a database connection. Ifname
is 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. Ifname
is 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.mod
toapp2
and rungo mod vendor
- Rename the chart in
./deploy/charts/app/Chart.yaml
toapp2
- Rename the directory
./deploy/charts/app
to./deploy/charts/app2
- Rename the directory in
./cmd/app
to./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/mongo
and 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.