Example CRUD project applying Hexagonal Architecture, Domain-Driven Design (DDD), Event-Driven Architecture (EDA), Command Query Responsibility Segregation (CQRS), Behavior-Driven Development (BDD), Continuous Integration (CI), and more... in Go.
go install github.com/bastean/codexgo/v4/cmd/codexgo@latest
Note
- We need to create an
.env
file where we have our own values defined.- In the .env.example.cli file, we can see the values that can be used.
- By omitting
CODEXGO_SMTP_*
, the link to confirm the account is sent through the Terminal with the following message: "Hi <username>, please confirm your account through this link: <link>".- We can define our own SMTP configuration by simply modifying the
CODEXGO_SMTP_*
variables, then we will be able to receive the links by mail.
- We can define our own SMTP configuration by simply modifying the
- By omitting
CODEXGO_BROKER_*
, an in-memory event bus will be used. - The only third-party service needed is the database
CODEXGO_DATABASE_*
, but in the next versions I will add a local implementation.
- By omitting
- In the .env.example.cli file, we can see the values that can be used.
codexgo -h
_________ ________________
_____________ ______ /_____ ____ __ __ ____/__ __ \
_ ___/_ __ \_ __ / _ _ \__ |/_/ _ / __ _ / / /
/ /__ / /_/ // /_/ / / __/__> < / /_/ / / /_/ /
\___/ \____/ \__,_/ \___/ /_/|_| \____/ \____/
Example CRUD project applying Hexagonal Architecture, DDD, EDA, CQRS, BDD, CI, and more... in Go.
Usage: codexgo [flags]
-env string
Path to ENV file (required)
Note
- System Requirements
- In the Demo version, the link to confirm the account is sent through the Terminal with the following message: "Hi <username>, please confirm your account through this link: <link>".
- We can define our own SMTP configuration in the .env.demo file by simply modifying the
CODEXGO_SMTP_*
variables, then we will be able to receive the links by mail.
- We can define our own SMTP configuration in the .env.demo file by simply modifying the
make demo
- Based on Standard Go Project Layout.
- Hooks managed by husky:
- Pre-Push:
- Scanning Repository for leaks using TruffleHog CLI and Trivy
- Pre-Commit: lint-staged
- Scanning files for leaks using TruffleHog CLI
- Formatting
- Commit-Msg: commitlint
- Check Conventional Commits rules
- Pre-Push:
- Commit message helper using Commitizen.
- Interactive prompt that allows you to write commits following the Conventional Commits rules:
make commit
- Interactive prompt that allows you to write commits following the Conventional Commits rules:
- TruffleHog CLI: Secrets.
- Trivy: Secrets, Vulnerabilities and Misconfigurations.
- OSV-Scanner: Vulnerabilities.
*.go
: gofmt, goimports and staticcheck.*.templ
: templ fmt.*.feature
(Gherkin): Cucumber extension.*.*
: Prettier cli/extension.
*.go
: deadcode.
- Random data generator: Gofakeit.
- Unit/Integration: Testify.
- Acceptance: Testify, Godog (Cucumber) and Playwright.
- Automatically managed by Release It!:
- Before/After Hooks for:
- Linting
- Testing
- Bump version based on Conventional Commits and SemVer:
- CHANGELOG generator
- Commits and Tags generator
- GitHub Releases
- Before/After Hooks for:
- Actions for:
- Setup Languages and Dependencies
- Workflows running:
- Automatically (Triggered by Push or Pull requests):
- Secrets Scanning (TruffleHog Action)
- Linting
- Testing
- Manually (Using the Actions tab on GitHub):
- Upgrade Dependencies
- Automate Release
- Automatically (Triggered by Push or Pull requests):
- Issue Templates (Defaults).
- Multiple Features already pre-configured:
- Go
- Node
- Docker in Docker
- Extensions and their respective settings to work with:
- Go
- templ
- Cucumber
- Gherkin
- Prettier
- Better Comments
- Todo Tree
- cSpell
- Dockerfile
- Multi-stage builds:
- Development
- Testing
- Build
- Production
- Multi-stage builds:
- Compose
- Switched by ENVs.
- Message (Event/Command):
- Routing Key based on AsyncAPI Topic Definition.
- Form validation at the client using Fomantic - Form Validation.
- On the server, the validations are performed using the Value Objects defined in the Context.
- Data authentication via JWT managed by Session Cookies.
- Account confirmation via Mail or Terminal.
- Password hashing using Bcrypt.
- Requests Rate Limiting.
- Server log files.
- syncenv
- Synchronize all .env* files in the directory using an .env model.
- copydeps
- Copies the files required by the browser dependencies from the node_modules folder and places them inside the static folder on the server.
- run
- Display the logs and redirect them to a file whose name depends on the time at which the service was run.
- Used in Production Image.
Bounded Context (App/Business/Department) > Modules (Troubleshooting) > Layers (Domain, Infrastructure & Application)
- Domain (Logic Core)
- Value Objects (Entities)
- Mother Creators
- Unit Tests
- Messages (Event/Command)
- Mother Creators
- Aggregates (Sets of Entities)
- Aggregate Root (Core Set)
- Mother Creators
- Role Interfaces (Ports)
- Repository
- Broker
- Model Interfaces
- Use Cases
- Handlers/Consumers
- Services (Abstract Logic)
- Errors (Management)
- Value Objects (Entities)
- Infrastructure (Port Adapters)
- Persistence
- Repository Mocks
- Implementations (Adapters)
- Integration Tests
- Communication
- Broker Mocks
- Implementations (Adapters)
- Integration Tests
- Persistence
- Application (Orchestration of Domain Logic)
- Use Cases
- Implementations
- Commands
- Mother Creators
- Queries/Responses
- Mother Creators
- Handlers/Consumers
- Implementations
- Unit Tests
- Use Cases
- Presentation (Consumers of Bounded Context Modules)
- Services (Mapping)
- Centralize Imports
- Initializations
- Server
- Templates
- Handlers
- API
- Views
- Routes
- API
/v*
- Views
- API
- Features (Gherkin)
- Acceptance Tests
- Services (Mapping)
The system allows users to register a new account, log in and update their data or permanently delete their account, as well as verify it through a link sent to their email.
It is a monolith where CRUD operations can be performed from different presentations to the same database, this allows us to manage users from the different presentations available, in addition to having a messaging system that allows to communicate the events occurred, thus avoiding a coupling to the source of the same.
-
pkg/context/(modules)
- It is the logical core that contains all the necessary functionalities that are agnostic of any presentation.
-
internal/pkg/service
- It is responsible for initializing all context functionalities so that they are ready for use, as well as for “mapping” certain values to centralize all imports required for presentations in a single place.
-
internal/app/(presentations)
- These applications will be used as presentations in order to serve the functionalities to an end user.
- Domain
errors.New*()
,errors.BubbleUp()
&errors.Panic()
- Only in the
Domain
layer and in the*_test.go
files can we throwerrors.Panic()
.
- Only in the
- Infrastructure
New*()
,Open()
&Close()
session
errors.New*()
&errors.BubbleUp()
- Application
Run()
,Handle()
&On()
errors.New*()
&errors.BubbleUp()
- Presentation
- Modules
Start()
&Stop()
errors.BubbleUp()
- Services / Apps
Init()
,Up()
&Down()
log.[Wrap]()
errors.New*()
&errors.BubbleUp()
- In
Apps
we will handleBubble Errors
.
- In
- Modules
- Main
log.Fatal()
&log.[Wrap]()
- Only
main()
can uselog.Fatal()
.
- Only
- Logs
[embed]
- We use
[]
to "embed" external values such as error messages, fields, etc... inside our messages.
- We use
- ENVs
os.[Getenv/LookupEnv]()
- Only handle
ENVs
directly in thePresentation
layer and in the*_test.go
files.- At the
Infrastructure
layer,ENVs
are received via arguments through function parameters.
- At the
- Only handle
- Blocks
const
,var
, &type
- We will group only those that are declared on a single line.
git clone https://github.com/bastean/codexgo.git && cd codexgo
git clone git@github.com:bastean/codexgo.git && cd codexgo
-
System Requirements
-
Start VS Code
code .
-
Open Command Palette
- Ctrl+Shift+P
-
Run
Dev Containers: Reopen in Container
Note
- System Requirements
- We need to change
<user>
and<repository>
with our own values.
curl -sSfLO https://github.com/bastean/codexgo/archive/refs/heads/main.zip \
&& unzip main.zip \
&& mv codexgo-main <repository> \
&& rm main.zip \
&& cd <repository> \
&& make genesis \
&& git commit -m "feat(genesis): codexgo" \
&& git branch -M main \
&& git remote add github https://github.com/<user>/<repository>.git \
&& git push -u github main \
&& git status
Important
These settings are necessary to be able to execute the Actions Workflows.
-
General
-
Workflow permissions
- Read and write permissions
-
-
Actions
-
New repository secret
-
BOT_GPG_PASSPHRASE
-
BOT_GPG_PRIVATE_KEY
gpg --armor --export-secret-key [Pub_Key_ID (*-BOT)]
-
-
Important
Before running it, we must initialize the following environment variable files:
- .env.example
- We will have to create a
.env.(dev|test|prod)
for each runtime environment. - In the .env.example.demo file, we can see the values that can be used.
- We will have to create a
In case we only want to run the Integration or Acceptance tests, in addition to having the .env.test
file, we must have the following files created:
- .env.example.test.integration
- Rename the file to
.env.test.integration
.
- Rename the file to
- .env.example.test.acceptance
- Rename the file to
.env.test.acceptance
.
- Rename the file to
make compose-dev
make test-unit
make compose-test-integration
make compose-test-acceptance
make compose-tests
make compose-prod
- Contributions and Feedback are always welcome!