Home

Awesome

Go Vertical Slice Template

A Golang boilerplate template, based on Vertical Slice Architecture and CQRS pattern with using Echo, Gorm, Zap, Viper, MediatR for CQRS and sarulabs/di for Dependency Injection.

You can use this project as a template to build your Backend project in the Go language on top of this project.

Features

Technologies - Libraries

Project Layout and Structure

projects structure is based on:

How to run the project?

We can run this Go boilerplate project with following steps:

How to run the tests?

# Run all tests
go test ./...

High Level Structure

│   .env
│   .gitignore
│   go.mod
│   go.sum
│   golangci.yml
│   readme.md
├───cmd
│   └───app
│           main.go
│
├───config
│       config.development.json
│       config.go
│
├───docs
│       docs.go
│       swagger.json
│       swagger.yaml
│
└───internal
    ├───catalogs
    │   ├───products
    │   │   │   mapper.go
    │   │   │
    │   │   ├───contracts
    │   │   │   │   endpoint.go
    │   │   │   │   product_respository.go
    │   │   │   │
    │   │   │   └───params
    │   │   │           product_route_params.go
    │   │   │
    │   │   ├───dtos
    │   │   │       product_dto.go
    │   │   │
    │   │   ├───features
    │   │   │   ├───creating_product
    │   │   │   │   ├───commands
    │   │   │   │   │       create_product.go
    │   │   │   │   │       create_product_handler.go
    │   │   │   │   │
    │   │   │   │   ├───dtos
    │   │   │   │   │       create_product_request_dto.go
    │   │   │   │   │       create_product_response.go
    │   │   │   │   │
    │   │   │   │   ├───endpoints
    │   │   │   │   │       create_product_endpoint.go
    │   │   │   │   │
    │   │   │   │   └───events
    │   │   │   │           product_created.go
    │   │   │   │           product_created_handler.go
    │   │   │   │
    │   │   │   └───getting_product_by_id
    │   │   │       ├───dtos
    │   │   │       │       get_product_by_id_request_dto.go
    │   │   │       │       get_product_by_id_response.go
    │   │   │       │
    │   │   │       ├───endpoints
    │   │   │       │       get_product_by_id_endpoint.go
    │   │   │       │
    │   │   │       └───queries
    │   │   │               get_product_by_id.go
    │   │   │               get_product_by_id_handler.go
    │   │   │
    │   │   ├───models
    │   │   │       product.go
    │   │   │
    │   │   └───repository
    │   │           inmemory_product_repository.go
    │   │
    │   └───shared
    │       ├───app
    │       │   ├───application
    │       │   │       application.go
    │       │   │       application_endpoints.go
    │       │   │       application_mediatr.go
    │       │   │       application_migration.go
    │       │   │
    │       │   └───application_builder
    │       │           application_builder.go
    │       │           application_builder_dependencies.go
    │       │
    │       └───behaviours
    │               request_logger_behaviour.go
    │
    └───pkg
        ├───config
        │   │   config_helper.go
        │   │   dependency.go
        │   │
        │   └───environemnt
        │           environment.go
        │
        ├───constants
        │       constants.go
        │
        ├───database
        │   │   db.go
        │   │   dependency.go
        │   │
        │   └───options
        │           gorm_options.go
        │
        └───reflection
            └───type_mappper
                    type_mapper.go
                    type_mapper_test.go
                    unsafe_types.go

Application Structure

In this project I used vertical slice architecture or Restructuring to a Vertical Slice Architecture also I used feature folder structure in this project.

Also here I used CQRS for decompose my features to very small parts that makes our application:

With using CQRS, our code will be more aligned with SOLID principles, especially with:

Here instead of some Technical Splitting for example a folder or layer for our services, controllers and data models which increase dependencies between our technical splitting and also jump between layers or folders, We cut each business functionality into some vertical slices, and inner each of these slices we have Technical Folders Structure specific to that feature (command, handlers, infrastructure, repository, controllers, data models, ...).

Usually, when we work on a given functionality we need some technical things for example:

Now we could all of these things beside each other and it decrease jumping and dependencies between some layers or folders.

Keeping such a split works great with CQRS. It segregates our operations and slices the application code vertically instead of horizontally. In Our CQRS pattern each command/query handler is a separate slice. This is where you can reduce coupling between layers. Each handler can be a separated code unit, even copy/pasted. Thanks to that, we can tune down the specific method to not follow general conventions (e.g. use custom SQL query or even different storage). In a traditional layered architecture, when we change the core generic mechanism in one layer, it can impact all methods.

Live Reloading In Development

For live reloading in dev mode I use air library. for guid about using this tools you can read this article.

For running app in live reload mode, inner type bellow command after installing air:

air