Awesome
<img src="https://img.shields.io/badge/Go-00ADD8?style=for-the-badge&logo=go&logoColor=white" /> <h1 align='center'> ⚡ go-vertical-slice-architecture </h1>This structure, created following the development guide's for vertical slice architecture, will help to isolate the dependencies, make development easier and have a cleaner and testable code in every package.
👩💻 Authors
Sebastián Ituarte
Luis Fernando Miranda
🖍 Vertical slice architecture
Vertical slice architecture is an approach to software development where code and functionality are organized around individual features or user stories, encompassing all layers of the application from user interface to data access, promoting autonomy, reduced dependencies, and iterative development.
📚 Code Structure
A brief description of the layout:
.github
has two template files for creating PR and issue. Please see the files for more details..gitignore
varies per project, but all projects need to ignorebin
directory..golangci.yml
is the golangci-lint config file.Makefile
is used to build the project. You need to tweak the variables based on your project.CHANGELOG.md
contains auto-generated changelog information.OWNERS
contains owners of the project.README.md
is a detailed description of the project.cmd
contains the main.go file that is our starting point to executepkg
places most of project business logic.migrations
contains all vendored code.internal
contains all the api logic.
🚀 Stack
Programming language Go
Framework Fiber
Dependency injection Uber dig
Database Postgre SQL
Container Docker
Live reload Air
🧐 This app uses conventional commits
🤜 How to create a new use case (Example)
POST /api/product
Parameter | Type | Description |
---|---|---|
name | string | Required. Product Name |
sku | string | Required. Product Sku must be Unique |
category | string | Required. Product Category |
price | float | Required. Product Price |
Internal folder structure for a new domain all folders and files go in internal/product/
├───internal
│ ├───product
│ │ │ port.go
│ │ │ product.go
│ │ │
│ │ ├───handler
│ │ │ createProduct.go
│ │ │ handler.go
│ │ │
│ │ ├───infrastructure
│ │ │ productRepository.go
│ │ │
│ │ ├───mock
│ │ │ mockProductRepository.go
│ │ │
│ │ └───service
│ │ createProduct.go
│ │ service.go
1 - Create product.go (domain)
2 - Create infrastructure/productRepository.go (DB query)
├───internal
│ ├───product
│ │ ├───infrastructure
│ │ │ productRepository.go
3 - Create port.go (dp injection for the service)
4 - Create service/createProduct.go (create a new product use case implementation)
├───internal
│ ├───product
│ │ └───service
│ │ createProduct.go
│ │ service.go
5 - Create service/service.go (dependency injection service using uber dig)
├───internal
│ ├───product
│ │ └───service
│ │ createProduct.go
│ │ service.go
6 - Create handler/createProduct.go (create a new hanlder presenter to call the use case)
├───internal
│ ├───product
│ │ ├───handler
│ │ │ createProduct.go
│ │ │ handler.go
7 - Create handler/handler.go (handles all the routes for all the presenters)
├───internal
│ ├───product
│ │ ├───handler
│ │ │ createProduct.go
│ │ │ handler.go
8 - Create mock/ProductRepository.go (mocks the user repository implementation for unit testing)
├───internal
│ ├───product
│ │ ├───mock
│ │ │ mockProductRepository.go
# It uses mockery Run
mockery
9 - Create service/createProduct_test.go (create a unit test for the service)
├───internal
│ ├───product
│ │ └───service
│ │ createProduct.go
│ │ service.go
10 - Add dependency injection service using uber dig
├───pkg
│ ├───injection
⚙️ Usage without Make
Docker usage
# Build server
docker-compose -p go-vertical-slice-architecture build
# Start server
docker-compose up -d
# Stop server
docker-compose down
Standalone usage
# Live reload
air
Testing
# To run unit testing
go test ./...
# To run unit testing coverage
go test -cover ./...
Formatting, Linting and Vetting
# Clean dependencies
go mod tidy
# Run formating
go fmt ./...
# Remove unused imports
goimports -l -w .
# Run linting
golangci-lint run ./...
# Run vetting
go vet ./...
# Run shadow to check shadowed variables
# Install shadow
go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow@latest
# Run shadow
shadow ./...
Database migration script
# Create the script
migrate create -ext sql -dir /migrations -seq [script_name]
# Run the script
migrate -database ${POSTGRESQL_URL} -path /migrations up
# It will run automatically when the database initializes
⚙️ Usage with Make
Docker usage
# Build server
make build-server
# Start server
make start-server
# Stop server
make stop-server
Standalone usage
# Live reload
make live-reload
Testing
# To run unit testing
make test
# To run unit testing coverage
make test-coverage
Formatting, Linting and Vetting
# Clean dependencies
make clean-deps
# Run formating
make format
# Remove unused imports
make clean-imports
# Run linting
make lint
# Run vetting
make vet
# Run shadow to check shadowed variables
# Install shadow
go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow@latest
# Run shadow
make check-shadow
# Run vetting to lint, format and vet your once
make lint-format
Database migration script
# Create the script (replace your_script_name with the actual name)
make migrate-create name=your_script_name
# Run the script
make migrate-up
# It will run automatically when the database initializes
💻 Environment variables
To modify/add configuration via environment variables, use the .env
file, which contains basic app configuration.