Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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

License

NotificationsYou must be signed in to change notification settings

mehdihadeli/go-vertical-slice-template

Repository files navigation

A Golang boilerplate template, based onVertical Slice Architecture andCQRS pattern with usingEcho,Gorm,Zap,Viper,MediatR for CQRS anduber-go/dig for Dependency Injection.

You can use this project as a template for building your backend application in Go, it's designed as a helpful starting point for your development.

Features

  • ✅ UsingVertical Slice Architecture as a high level architecture
  • ✅ UsingData Centric Architecture based on CRUD
  • ✅ UsingCQRS Pattern andMediator Patternon top ofmehdihadeli/Go-MediatR library
  • ✅ UsingDependency Injection andInversion of Controlon top ofuber-go/dig library
  • ✅ UsingRESTFul api withEcho framework andOpen-Api using swagger withswaggo/swag library
  • ✅ Usinggo-playground/validator for validating input data in the REST and gRpc
  • ✅ UsingGorm andSQLLite for databases
  • ✅ UsingZap for Logging
  • ✅ UsingViper for configuration management

Technologies - Libraries

  • ✔️labstack/echo - High performance, minimalist Go web framework
  • ✔️uber-go/zap - Blazing fast, structured, leveled logging in Go.
  • ✔️emperror/errors - Drop-in replacement for the standard library errors package and github.com/pkg/errors
  • ✔️stretchr/testify - A toolkit with common assertions and mocks that plays nicely with the standard library
  • ✔️mehdihadeli/go-mediatr - Mediator pattern implementation in Golang and helpful in creating CQRS based applications.
  • ✔️swaggo/swag - Automatically generate RESTful API documentation with Swagger 2.0 for Go.
  • ✔️go-gorm/gorm - The fantastic ORM library for Golang, aims to be developer friendly
  • ✔️go-playground/validator - Go Struct and Field validation, including Cross Field, Cross Struct, Map, Slice and Array diving
  • ✔️uber-go/dig - A reflection based dependency injection toolkit for Go.
  • ✔️spf13/viper - Go configuration with fangs
  • ✔️caarlos0/env - A simple and zero-dependencies library to parse environment variables into structs.
  • ✔️joho/godotenv - A Go port of Ruby's dotenv library (Loads environment variables from .env files)
  • ✔️mcuadros/go-defaults - Go structures with default values using tags

Project Layout and Structure

projects structure is based on:

How to run the project?

We can run this Go boilerplate project with following steps:

  • Clone this project.
  • Move to your workspace:cd your-workspace.
  • Clone this project into your workspace:git clone https://github.com/mehdihadeli/go-vertical-slice-template.
  • Move to the project root directory:cd go-vertical-slice-template.
  • Create a file.env similar to existing.env file at the root directory for your environment variables.
  • Add application configurations based on enviroment (dev or production) inconfig/config.development.json orconfig.production.json files.
  • Installgo if not installed on your machine.
  • Rungo run cmd/app/main.go.
  • Access API usinghttp://localhost:9080.

How to run the tests?

# Run all testsgotest ./...

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 usedvertical slice architecture orRestructuring to a Vertical Slice Architecture also I usedfeature folder structure in this project.

  • We treat each request as a distinct use case or slice, encapsulating and grouping all concerns from front-end to back.
  • When We are adding or changing a feature in an application in n-tire architecture, we are typically touching many different "layers" in an application. we are changing the user interface, adding fields to models, modifying validation, and so on. Instead of coupling across a layer, we couple vertically along a slice and each change affects only one slice.
  • WeMinimize couplingbetween slices, andmaximize couplingin a slice.
  • With this approach, each of our vertical slices can decide for itself how to best fulfill the request. New features only add code, we're not changing shared code and worrying about side effects. For implementing vertical slice architecture using cqrs pattern is a good match.

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

  • maximize performance, scalability and simplicity.
  • adding new feature to this mechanism is very easy without any breaking change in other part of our codes. New features only add code, we're not changing shared code and worrying about side effects.
  • easy to maintain and any changes only affect on one command or query (or a slice) and avoid any breaking changes on other parts
  • it gives us better separation of concerns and cross-cutting concern (with help of MediatR behavior pipelines) in our code instead of a big service class for doing a lot of things.

With usingCQRS, our code will be more aligned withSOLID principles, especially with:

  • Single Responsibility rule - because logic responsible for a given operation is enclosed in its own type.
  • Open-Closed rule - because to add new operation you don’t need to edit any of the existing types, instead you need to add a new file with a new type representing that operation.

Here instead of someTechnical Splitting for example a folder or layer for ourservices,controllers anddata 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 haveTechnical 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:

  • API endpoint (Controller)
  • Request Input (Dto)
  • Request Output (Dto)
  • Some class to handle Request, For example Command and Command Handler or Query and Query Handler
  • Data Model

Now we could all of these things beside each other, and it decreases 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 useair library. for guid about using this tools you canread this article.

For running app inlive reload mode, inner type bellow command afterinstalling air:

air

About

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

Topics

Resources

License

Stars

Watchers

Forks

Languages


[8]ページ先頭

©2009-2025 Movatter.jp