Skip to content

Commit

Permalink
feat: introduce v4 (#88)
Browse files Browse the repository at this point in the history
* chore: initial the new code structure

* feat: restrcuture the code directory

* chore: add minor comment

* fix: use go-generate for mockery

* fix: typos

* chore: fix typos

* chore: rename usecase to service for better clarity

* chore: rename to service

* chore: fix typo

* chore: add author's note
  • Loading branch information
bxcodec authored Feb 18, 2024
1 parent d5d2bac commit beb599f
Show file tree
Hide file tree
Showing 35 changed files with 631 additions and 529 deletions.
2 changes: 2 additions & 0 deletions .air.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ full_bin = "./tmp_app/app/engine"
log = "air_errors.log"
# Watch these filename extensions.
include_ext = ["go", "yaml", "toml"]
# Exclude specific regular expressions.
exclude_regex = ["_test\\.go"]
# Ignore these filename extensions or directories.
exclude_dir = ["tmp_app", "tmp"]
# It's not necessary to trigger build each time file changes if it's too frequent.
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ _*
.DS_Store
engine
bin/
*.out
*.out
tmp_app/
.env
119 changes: 29 additions & 90 deletions .golangci.yaml
Original file line number Diff line number Diff line change
@@ -1,42 +1,4 @@
linters-settings:
dupl:
threshold: 300
funlen:
lines: 200
statements: 55
goconst:
min-len: 2
min-occurrences: 3
gocritic:
enabled-tags:
- diagnostic
- experimental
- performance
- style
- opinionated
disabled-checks:
- dupImport # https://github.com/go-critic/go-critic/issues/845
- ifElseChain
- octalLiteral
- whyNoLint
- wrapperFunc
- hugeParam
gocyclo:
min-complexity: 20
gomnd:
# don't include the "operation" and "assign"
checks:
- argument
- case
- condition
- return
ignored-numbers:
- "0"
- "1"
- "2"
- "3"
ignored-functions:
- strings.SplitN
govet:
check-shadowing: true
settings:
Expand All @@ -46,85 +8,62 @@ linters-settings:
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf
lll:
line-length: 160
gocyclo:
min-complexity: 50
maligned:
suggest-new: true
dupl:
threshold: 100
goconst:
min-len: 2
min-occurrences: 2
misspell:
locale: US
nolintlint:
allow-leading-space: true # don't require machine-readable nolint directives (i.e. with no leading space)
allow-unused: false # report any unused nolint directives
require-explanation: false # don't require an explanation for nolint directives
require-specific: false # don't require nolint directives to be specific about which linter is being skipped
revive:
confidence: 0.8
lll:
line-length: 160
# tab width in spaces. Default to 1.
tab-width: 1
funlen:
lines: 150
statements: 80

linters:
# please, do not use `enable-all`: it's deprecated and will be removed soon.
# inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint
disable-all: true
enable:
- asciicheck
- bodyclose
# - deadcode
- depguard
- dogsled
- dupl
- errcheck
- exportloopref
- funlen
- gochecknoinits
- goconst
- gocritic
- gocyclo
- gofmt
- goimports
- gomnd
- goprintffuncname
- gosec
- gosimple
- govet
- ineffassign
- lll
- misspell
- nakedret
- noctx
# - nolintlint
- revive
- staticcheck
# - structcheck
- stylecheck
- typecheck
- unconvert
- unparam
- unused
- revive
# - varcheck
- whitespace

# don't enable:
#
# - scopelint
# - gochecknoglobals
# - gocognit
# - godot
# - godox
# - goerr113
# - interfacer
# - maligned
# - nestif
# - prealloc
# - testpackage
# - wsl

issues:
# Excluding configuration per-path, per-linter, per-text and per-source
exclude-rules:
- path: _test\.go
linters:
- gomnd
- dupl
- goconst

# - path: pkg/xerrors/xerrors.go
# text: "SA1019: errCfg.Exclude is deprecated: use ExcludeFunctions instead"
- path: app
text: "don't use `init` function"
run:
timeout: 5m
go: "1.17"
skip-dirs:
# - */mocks
# - test/testdata_etc
skip-files:
- ".*_test\\.go$"

issues:
exclude-rules:
#
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Builder
FROM golang:1.19.4-alpine3.17 as builder
FROM golang:1.20.7-alpine3.17 as builder

RUN apk update && apk upgrade && \
apk --update add git make bash build-base
Expand Down
47 changes: 26 additions & 21 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ export PATH := $(PWD)/bin:$(PATH)
# Default Shell
export SHELL := bash
# Type of OS: Linux or Darwin.
export OSTYPE := $(shell uname -s)
export OSTYPE := $(shell uname -s | tr A-Z a-z)
export ARCH := $(shell uname -m)



# --- Tooling & Variables ----------------------------------------------------------------
Expand All @@ -23,7 +25,7 @@ down: docker-stop ## Stop Docker
destroy: docker-teardown clean ## Teardown (removes volumes, tmp files, etc...)

install-deps: migrate air gotestsum tparse mockery ## Install Development Dependencies (localy).
deps: $(MIGRATE) $(AIR) $(GOTESTSUM) $(TPARSE) $(MOCKERY) ## Checks for Global Development Dependencies.
deps: $(MIGRATE) $(AIR) $(GOTESTSUM) $(TPARSE) $(MOCKERY) $(GOLANGCI) ## Checks for Global Development Dependencies.
deps:
@echo "Required Tools Are Available"

Expand Down Expand Up @@ -89,11 +91,11 @@ TESTS_ARGS += -test.coverprofile coverage.out
TESTS_ARGS += -test.timeout 5s
TESTS_ARGS += -race

run-tests: $(GOTESTSUM)
tests: $(GOTESTSUM)
@ gotestsum $(TESTS_ARGS) -short

tests: run-tests $(TPARSE) ## Run Tests & parse details
@cat gotestsum.json.out | $(TPARSE) -all -top -notests
tests-complete: tests $(TPARSE) ## Run Tests & parse details
@cat gotestsum.json.out | $(TPARSE) -all -notests

# ~~~ Docker Build ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand All @@ -105,28 +107,31 @@ image-build:
--tag go-clean-arch \
.

# ~~~ Database Migrations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Commenting this as this not relevant for the project, we load the DB data from the SQL file.
# please refer this when introducing the database schema migrations.

# # ~~~ Database Migrations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


MYSQL_DSN := "mysql://$(MYSQL_USER):$(MYSQL_PASSWORD)@tcp($(MYSQL_ADDRESS))/$(MYSQL_DATABASE)"
# MYSQL_DSN := "mysql://$(MYSQL_USER):$(MYSQL_PASSWORD)@tcp($(MYSQL_ADDRESS))/$(MYSQL_DATABASE)"

migrate-up: $(MIGRATE) ## Apply all (or N up) migrations.
@ read -p "How many migration you wants to perform (default value: [all]): " N; \
migrate -database $(MYSQL_DSN) -path=misc/migrations up ${NN}
# migrate-up: $(MIGRATE) ## Apply all (or N up) migrations.
# @ read -p "How many migration you wants to perform (default value: [all]): " N; \
# migrate -database $(MYSQL_DSN) -path=misc/migrations up ${NN}

.PHONY: migrate-down
migrate-down: $(MIGRATE) ## Apply all (or N down) migrations.
@ read -p "How many migration you wants to perform (default value: [all]): " N; \
migrate -database $(MYSQL_DSN) -path=misc/migrations down ${NN}
# .PHONY: migrate-down
# migrate-down: $(MIGRATE) ## Apply all (or N down) migrations.
# @ read -p "How many migration you wants to perform (default value: [all]): " N; \
# migrate -database $(MYSQL_DSN) -path=misc/migrations down ${NN}

.PHONY: migrate-drop
migrate-drop: $(MIGRATE) ## Drop everything inside the database.
migrate -database $(MYSQL_DSN) -path=misc/migrations drop
# .PHONY: migrate-drop
# migrate-drop: $(MIGRATE) ## Drop everything inside the database.
# migrate -database $(MYSQL_DSN) -path=misc/migrations drop

.PHONY: migrate-create
migrate-create: $(MIGRATE) ## Create a set of up/down migrations with a specified name.
@ read -p "Please provide name for the migration: " Name; \
migrate create -ext sql -dir misc/migrations $${Name}
# .PHONY: migrate-create
# migrate-create: $(MIGRATE) ## Create a set of up/down migrations with a specified name.
# @ read -p "Please provide name for the migration: " Name; \
# migrate create -ext sql -dir misc/migrations $${Name}

# ~~~ Cleans ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
26 changes: 21 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,24 @@
Proposed on 2018, archived to v2 branch on 2020 <br>
Desc: Improvement from v1. The story can be read here: https://medium.com/@imantumorang/trying-clean-architecture-on-golang-2-44d615bf8fdf

- **v3**: master branch <br>
- **v3**: checkout to the [v3 branch](https://github.com/bxcodec/go-clean-arch/tree/v3) <br>
Proposed on 2019, merged to master on 2020. <br>
Desc: Introducing Domain package, the details can be seen on this PR [#21](https://github.com/bxcodec/go-clean-arch/pull/21)

- **v4**: master branch
Proposed on 2024, merged to master on 2024. <br>
Desc:

- Declare Interfaces to the consuming side,
- Introduce `internal` package
- Introduce `Service-focused` package.

Details can be seen in this PR [#88](https://github.com/bxcodec/go-clean-arch/pull/88).<br>

> ### Author's Note
>
> You may notice it diverges from the structures seen in previous versions. I encourage you to explore the branches for each version to select the structure that appeals to you the most. In my recent projects, the code structure has progressed to version 4. However, I do not strictly advocate for one version over another. You may encounter alternative examples on the internet that align more closely with your preferences. Rest assured, the foundational concept will remain consistent or at least bear resemblance. The differences are primarily in the arrangement of directories or the integration of advanced tools directly into the setup.
## Description

This is an example of implementation of Clean Architecture in Go (Golang) projects.
Expand All @@ -40,14 +54,13 @@ This project has 4 Domain layer :
![golang clean architecture](https://github.com/bxcodec/go-clean-arch/raw/master/clean-arch.png)

The original explanation about this project's structure can read from this medium's post : https://medium.com/@imantumorang/golang-clean-archithecture-efd6d7c43047.

It may different already, but the concept still the same in application level, also you can see the change log from v1 to current version in Master.
It may be different already, but the concept still the same in application level, also you can see the change log from v1 to current version in Master.

### How To Run This Project

> Make Sure you have run the article.sql in your mysql
Since the project already use Go Module, I recommend to put the source code in any folder but GOPATH.
Since the project is already use Go Module, I recommend to put the source code in any folder but GOPATH.

#### Run the Testing

Expand All @@ -69,6 +82,9 @@ $ git clone https://github.com/bxcodec/go-clean-arch.git
#move to project
$ cd go-clean-arch

# copy the example.env to .env
$ cp example.env .env

# Run the application
$ make up

Expand All @@ -80,7 +96,7 @@ $ curl localhost:9090/articles

### Tools Used:

In this project, I use some tools listed below. But you can use any simmilar library that have the same purposes. But, well, different library will have different implementation type. Just be creative and use anything that you really need.
In this project, I use some tools listed below. But you can use any similar library that have the same purposes. But, well, different library will have different implementation type. Just be creative and use anything that you really need.

- All libraries listed in [`go.mod`](https://github.com/bxcodec/go-clean-arch/blob/master/go.mod)
- ["github.com/vektra/mockery".](https://github.com/vektra/mockery) To Generate Mocks for testing needs.
Loading

0 comments on commit beb599f

Please sign in to comment.