# README
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.
Showcase





CLI
Installation
go install github.com/bastean/codexgo/v4/cmd/codexgo@latest
Usage
[!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.
- If
CODEXGO_SMTP_*
is omitted, 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.- If
CODEXGO_BROKER_*
is omitted, an in-memory event bus will be used.- If
CODEXGO_DATABASE_*
is omitted, aSQLite
in-memory database will be used.
- We can use a file as a database instead of memory by defining the file name in the
CODEXGO_DATABASE_SQLITE_DSN
variable.
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)
Docker
Usage (Demo)
[!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.
make demo
Features
Project Layout
- Based on Standard Go Project Layout.
Git
- 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:
Scanners
- TruffleHog CLI: Secrets.
- Trivy: Secrets, Vulnerabilities and Misconfigurations.
- OSV-Scanner: Vulnerabilities.
Linters/Formatters
*.go
: gofmt, goimports and staticcheck.*.templ
: templ fmt.*.feature
(Gherkin): Cucumber extension.*.*
: Prettier cli/extension.
Debuggers
*.go
: deadcode.
Tests
- Random data generator: Gofakeit.
- Unit/Integration: Testify.
- Acceptance: Testify, Godog (Cucumber) and Playwright.
Releases
- 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:
GitHub
- 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).
Devcontainer
- 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
Docker
- Dockerfile
- Multi-stage builds:
- Development
- Testing
- Build
- Production
- Multi-stage builds:
- Compose
- Switched by ENVs.
Broker
- Message (Event/Command):
- Routing Key based on AsyncAPI Topic Definition.
Security
- 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.
Scripts
- 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.
Domain > (Infrastructure | Application) > Presentation
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
Services > App > (Presentation)
- 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)
Workflow
Idea
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.
Functionality
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.
Folders
-
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.
Idiomatic
- 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.
First Steps
Clone
HTTPS
git clone https://github.com/bastean/codexgo.git && cd codexgo
SSH
git clone [email protected]:bastean/codexgo.git && cd codexgo
Initialize
Dev Container (recommended)
-
System Requirements
-
Start VS Code
code .
-
Open Command Palette
- Ctrl+Shift+P
-
Run
Dev Containers: Reopen in Container
Locally
ZIP
[!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
GitHub Repository
[!IMPORTANT] These settings are necessary to be able to execute the Actions Workflows.
Settings tab
Actions
-
General
-
Workflow permissions
- Read and write permissions
-
Secrets and variables
-
Actions
-
New repository secret
-
BOT_GPG_PASSPHRASE
-
BOT_GPG_PRIVATE_KEY
gpg --armor --export-secret-key [Pub_Key_ID (*-BOT)]
-
-
Run
ENVs
[!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.
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
.- .env.example.test.acceptance
- Rename the file to
.env.test.acceptance
.
Development
make compose-dev
Tests
Unit
make test-unit
Integration
make compose-test-integration
Acceptance
make compose-test-acceptance
Unit / Integration / Acceptance
make compose-tests
Production
make compose-prod
Tech Stack
Base
Please see
Contributing
- Contributions and Feedback are always welcome!