create a CRUD API using Hexagonal Architecture

create a CRUD API using Hexagonal Architecture

Hai! Welcome to my article. In this article, I will discuss a project I recently worked on. I have been trying to create a CRUD API using Hexagonal Architecture, an architecture that has a lot in common with Clean Architecture. To make it easier to understand, I will divide this article into several parts as listed below :

Hexagonal Architecture .?

Hexagonal Architectur, also known as Ports and Adapters Architecture, is a software architecture that aims to separate business logic from external infrastructure. This allows applications to be more flexible, easy to test, and not dependent on any particular framework or technology. The following is a structured explanation of Hexagonal Architecture :

1. Core/Domain

Entities: Entities are business objects that represent important concepts in an application domain. Example: User, Order.

Use Cases/Services: This is the core business logic that processes entities to meet application needs. Use Cases represent specific business scenarios, such as "Create Order" or "Register User".

Domain Events: An option that allows parts of a domain to communicate or trigger actions in other parts of the system without needing to know implementation details.

2. Ports

Primary Ports (Driving): Interfaces used by applications to receive input from the outside world (for example, an API to receive HTTP requests from clients).

Secondary Ports (Driven): Interfaces used by the domain to communicate with external components, such as databases, external services, or other systems (for example, repository interfaces).

3. Adapters

Primary Adapters: Implement primary port interfaces to connect applications with users or external systems. Example: Controller in a web application, command line interface (CLI).

Secondary Adapters: Implement secondary port interfaces to connect the domain with external services or infrastructure such as databases, message brokers, or other services. Example: Repository implementation, client service.

4. Application Layer (Optional)

Some hexagonal architecture implementations add an application layer that handles use case orchestration, transaction management, and workflow coordination, without containing any business logic itself.

5. Infrastructure

Infrastructure is everything related to technical implementation details, such as ORM, database connections, framework configuration, and so on. This section is separate from the domain to ensure that the domain does not rely on these technical details.

6. Main Benefits

Business Logic Isolation: By separating business logic from infrastructure, you can change external technology without changing business logic.

Ease of Testing: Each layer can be tested independently, making unit testing and integration testing easier and more effective.

Flexibility: Easily adapt to changing business or technology needs.

7. Implementation Example

For example, in a product application, there is a Product domain. The primary adapter may be a REST API that accepts requests to create orders, while the secondary adapter may be a repository implementation that stores Products in a database.

8. Interaction

Users or external systems interact with applications through primary ports and primary adapters.

Domains interact with external services or infrastructure through secondary ports and secondary adapters.

By separating applications into well-defined layers, Hexagonal Architecture enables great flexibility in development, maintenance, and future development of applications.


Preparation for Project Creation

  1. Golang
  2. MongoDB
  3. Postman

When you have installed everything needed, the next step is to create a database, using MongoDB, with the name db-store, and create a collection with the name product.


Article content

create a go project using your respective editor, and name it hexagol_curd

The following is the folder structure that I created, and the explanation :

HEXAGONAL_CRUD
├─ api
│    ├── product
│             ├── adapter.go
│             ├── handler.go
├─ cmd
│    ├── main.go
├─ domain
│    ├── product
│             ├── product.go
│             ├── service.go
├─ infrastructure
│     ├── mongo.db.go
│     ├── opentelemetry.go
├─ repository
│    ├── product
│             ├── repository.go
├─ service
│    ├── product
│             ├── adapter.go
├─ utils
│     ├── http.go
│     ├── utils.go
│     ├── validator.go
├─ .env
├─ go.mod
├─ go.sum        

Add this defense to the terminal

go get github.com/gofiber/contrib/otelfiber/v2@v2.0.0-20231127213504-cd551bc2983e
go get github.com/gofiber/fiber/v2@v2.51.0
go get github.com/joho/godotenv@v1.5.1
go get github.com/kelseyhightower/envconfig@v1.4.0
go get github.com/rl404/fairy@v0.21.0
go get github.com/stretchr/testify@v1.8.4
go get go.mongodb.org/mongo-driver@v1.12.1
go get go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo@v0.42.0
go get go.opentelemetry.io/otel@v1.21.0
go get go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@v1.21.0
go get go.opentelemetry.io/otel/exporters/stdout/stdoutmetric@v0.44.0
go get go.opentelemetry.io/otel/sdk@v1.21.0
go get go.opentelemetry.io/otel/sdk/metric@v1.21.0
go get go.opentelemetry.io/otel/trace@v1.21.0

go get github.com/andybalholm/brotli@v1.0.5 
go get github.com/cenkalti/backoff/v4@v4.2.1 
go get github.com/davecgh/go-spew@v1.1.1 
go get github.com/go-logr/logr@v1.3.0 
go get github.com/go-logr/stdr@v1.2.2 
go get github.com/go-playground/locales@v0.14.0 
go get github.com/go-playground/mold/v4@v4.2.0 
go get github.com/go-playground/universal-translator@v0.18.0 
go get github.com/go-playground/validator/v10@v10.11.1 
go get github.com/golang/protobuf@v1.5.3 
go get github.com/golang/snappy@v0.0.4 
go get github.com/google/uuid@v1.4.0 
go get github.com/grpc-ecosystem/grpc-gateway/v2@v2.16.0 
go get github.com/klauspost/compress@v1.16.7 
go get github.com/leodido/go-urn@v1.2.1 
go get github.com/mattn/go-colorable@v0.1.13 
go get github.com/mattn/go-isatty@v0.0.20 
go get github.com/mattn/go-runewidth@v0.0.15 
go get github.com/montanaflynn/stats@v0.0.0-20171201202039-1bf9dbcd8cbe 
go get github.com/pmezard/go-difflib@v1.0.0 
go get github.com/rivo/uniseg@v0.2.0 
go get github.com/segmentio/go-camelcase@v0.0.0-20160726192923-7085f1e3c734 
go get github.com/segmentio/go-snakecase@v1.2.0 
go get github.com/valyala/bytebufferpool@v1.0.0 
go get github.com/valyala/fasthttp@v1.50.0 
go get github.com/valyala/tcplisten@v1.0.0 
go get github.com/xdg-go/pbkdf2@v1.0.0 
go get github.com/xdg-go/scram@v1.1.2 
go get github.com/xdg-go/stringprep@v1.0.4 
go get github.com/youmark/pkcs8@v0.0.0-20181117223130-1be2e3e5546d 
go get go.opentelemetry.io/contrib@v1.20.0 
go get go.opentelemetry.io/otel/exporters/otlp/otlptrace@v1.21.0 
go get go.opentelemetry.io/otel/metric@v1.21.0 
go get go.opentelemetry.io/proto/otlp@v1.0.0 
go get golang.org/x/crypto@v0.16.0 
go get golang.org/x/net@v0.19.0 
go get golang.org/x/sync@v0.4.0 
go get golang.org/x/sys@v0.15.0 
go get golang.org/x/text@v0.14.0 
go get google.golang.org/genproto/googleapis/api@v0.0.0-20231002182017-d307bd883b97 
go get google.golang.org/genproto/googleapis/rpc@v0.0.0-20231012201019-e917dd12ba7a 
go get google.golang.org/grpc@v1.59.0 
go get google.golang.org/protobuf@v1.31.0 
go get gopkg.in/yaml.v3@v3.0.1        

Check the code here, to see the coding logic

After following the coding logic, check the API in postman :

  • Api Post Products

Article content

  • Api Get Product

Article content

  • Api Get Product {Id}

Article content


Hey Rivaldy... Do you have a public github repo that implements a well strucuture and large project using Hexagonal architecture? I just found several repos but implementing basic examples. I was looking for a complex and huge project to see how to manage the complexity using hexagonal architecture in microservices.... thanks

Like
Reply

To view or add a comment, sign in

More articles by Rivaldy Mechdivicka

Others also viewed

Explore content categories