Skip to content
/ codexgo Public template

Example CRUD project applying Hexagonal Architecture, DDD, EDA, CQRS, BDD, CI, and more... in Go.

License

Notifications You must be signed in to change notification settings

bastean/codexgo

Repository files navigation

README Logo

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.


License MIT Go Report Card Commitizen friendly Release It!

Upgrade workflow CI workflow Release workflow

Go Reference GitHub Releases

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.
      • 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.
      • 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.
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

Git

Scanners

Linters/Formatters

Debuggers

Tests

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

GitHub

  • Actions for:
    • Setup Languages and Dependencies
  • Workflows running:
    • Automatically (Triggered by Push or Pull requests):
    • Manually (Using the Actions tab on GitHub):
      • Upgrade Dependencies
      • Automate Release
  • 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
  • Compose
    • Switched by ENVs.

Broker

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)
  • Infrastructure (Port Adapters)
    • Persistence
      • Repository Mocks
      • Implementations (Adapters)
      • Integration Tests
    • Communication
      • Broker Mocks
      • Implementations (Adapters)
      • Integration Tests
  • Application (Orchestration of Domain Logic)
    • Use Cases
      • Implementations
    • Commands
      • Mother Creators
    • Queries/Responses
      • Mother Creators
    • Handlers/Consumers
      • Implementations
      • Unit Tests

Services > App > (Presentation)

  • Presentation (Consumers of Bounded Context Modules)
    • Services (Mapping)
      • Centralize Imports
      • Initializations
    • Server
      • Templates
      • Handlers
        • API
        • Views
      • Routes
        • API /v*
        • Views
      • Features (Gherkin)
        • Acceptance Tests

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

  1. pkg/context/(modules)

    • It is the logical core that contains all the necessary functionalities that are agnostic of any presentation.
  2. 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.
  3. 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 throw errors.Panic().
  • 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 handle Bubble Errors.
  • Main
    • log.Fatal() & log.[Wrap]()
      • Only main() can use log.Fatal().
  • Logs
    • [embed]
      • We use [] to "embed" external values such as error messages, fields, etc... inside our messages.
  • ENVs
    • os.[Getenv/LookupEnv]()
      • Only handle ENVs directly in the Presentation layer and in the *_test.go files.
        • At the Infrastructure layer, ENVs are received via arguments through function parameters.
  • 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 git@github.com:bastean/codexgo.git && cd codexgo

Initialize

Dev Container (recommended)

  1. System Requirements

  2. Start VS Code

    code .
  3. Open Command Palette

    • Ctrl+Shift+P
  4. Run

    Dev Containers: Reopen in Container
    

Locally

  1. System Requirements

  2. Run

    make init

ZIP

Note

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:

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

License