Go-clean-template

Go-clean-template: Clean Architecture template for Golang services

Go-clean-template is a Golang template project based on Robert "Uncle Bob" Martin’s Clean Architecture principles, ready for you to clone and use as a starting point for your next Golang app.

The Clean Architecture

The Clean Architecture is a way of arranging complex — or potentially-complex — systems which, like most good sets of architectural principles, promotes a strict separation of concerns.

That is, software is broken down into independent functional components which interface with one another only through well-defined and reliable means, with only the state and resources which need to be exchanged in order to perform the task at hand passed between them.

A strict separation of concerns can help minimise the complexity of each component, reducing the likelihood of bugs being introduced, and making them easier to fix when they do arise — provided the offending component can be readily identified. A separation of concerns is key to adhering to the least privilege security principle.

This is all in contrast to monolithic software, where all of the code for the system is in effect bundled together and given access to all of the same resources with equal privilege, and so properly-functioning monolithic systems ultimately rely upon people not making mistakes (which, inevitably, they do).

The Clean Architecture achieves this separation of concerns through conventions (rules) which make it clear where within the architecture an entity, component, or part of a component exists, and the extent to which each is visible and accessible to other parts of the system.

For example, the high-level enterprise business rules of a system cannot, if you conform to the Clean Architecture principles, have direct access to data structures passed between an API server and a mobile app, nor even have awareness that such details exist — although their content can of course be passed through the layers from the low-level components to the higher ones through well-defined means if that is required functionality.

Of course, like all architectural foundations, the Clean Architecture is a framework that you have to choose to adhere to throughout the lifecycle of a piece of software, it won't physically prevent you from writing poor code. Hopefully, though, starting with this template will help you start as you mean to go on!

 

Quick Start

Once you've checked out the template, you can dive into internal and start writing code. The provided Makefile has a number of targets for building and running your app, but the most useful ones are:

Run with Docker (starts Postgres and RabbitMQ):

$ make compose-up

Run locally with migrations:

$ make run

Run integration tests with Docker:

$ make compose-up-integration-test

Project Structure

Full details are included in the project's README, but some areas of particular interest include:

cmd/app/main.go

Configuration and logger initialisation, before control is passed to Run in internal/app/app.go.

internal/app

The Run function (invoked by Main) in app.go performs object initialisation and dependency injection (more on this below), starts the server, and waits until it's time to gracefully terminate.

The migrate.go file is used for database auto migrations. It is included if an argument with the migrate tag is specified. For example: 

$ go run -tags migrate ./cmd/app

internal/delivery

Server handler layer (MVC controllers). The template includes two servers:

  • RPC (RabbitMQ as transport)
  • REST HTTP (Gin framework)

Server routers are written in the same style:

  • Handlers are grouped by area of application
  • For each group, its own router structure is created, the methods of which process paths
  • The structure of the business logic is injected into the router structure, which will be called by the handlers

internal/domain

Business logic models that are common to the system and can be used in any layer.

internal/service

Business logic.

  • Methods are grouped by area of application (on a common basis)
  • Each group has its own structure
  • One file - one structure

config/config.yml

Application configuration. Environment variables will override configuration file values. Configuration options with the tag 'env-required: true' in config.go are required, and a value must be provided in either config.yml, the environment, or both.

docs/

Swagger documentation. This is auto-generated by swag library, so don't make any changes, as they'll be lost.

integration-test/

Integration tests. They are launched as a separate container, next to the application container. It is convenient to test the Rest API using go-hit.

Dependency Injection

We make use of dependency injection in order to enable a weak coupling between components and minimise direct dependencies.

For example, through the NewService constructor, we inject the dependency into the structure of the business logic. This makes the business logic independent (and portable). We can override the implementation of the interface without making changes to the service package.

package service

import (
    // Nothing!
)

type Repository interface {
    Get()
}

type Service struct {
    repo Repository
}

func NewService(r Repository) *Service{
    return &Service{r}
}

func (s *Service) Do()  {
    s.repo.Get()
}

This also allows us to auto-generate mocks (for example with mockery) and easily write unit tests.

We are not tied to specific implementations in order to always be able to change one component to another. If the new component implements the interface, nothing needs to be changed in the business logic.

If you find you need to managing a large number of injections, wire is a popular choice.

Alternative projects

Of course ours isn't the only Clean Architecture template for Golang, so you may be interested to explore these alternatives and choose the one that suits you best:

  • go-clean-arch
  • courses-backend

Our work on open-source projects proves our initiative & understanding of what developers love and need. Reach out to us via the form below if you need to update your project to the latest versions of the technology stack!

Often, problems with architecture arise after most of the project has been written. And Clean Architecture helps delay decision making, making your code simpler and more maintainable.
Mikhail Nepryakhin
go-clean-template core contributor
Contact us
Have a project in mind?
Let's make it happen
Attach file
Files must be less than 8 MB.
Allowed file types: jpg jpeg png txt rtf pdf doc docx ppt pptx.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.