Clean Architecture, the right way
What is so Clean about Clean Architecture?

In short, you get the following benefits from using Clean Architecture:

Database Agnostic : Your core business logic does not care if you are using Postgres, MongoDB, or Neo4J for that matter.

: Your core business logic does not care if you are using Postgres, MongoDB, or Neo4J for that matter. Client Interface Agnostic: The core business logic does not care if you are using a CLI, a REST API, or even gRPC.

The core business logic does not care if you are using a CLI, a REST API, or even gRPC. Framework Agnostic: Using vanilla nodeJS, express, fastify? Your core business logic does not care about that either.

Now if you want to read more about how clean architecture works, you can read the fantastic blog, The Clean Architecture, by Uncle Bob. For now, lets jump to the implementation. To follow along, view the repository here.

Clean-Architecture-Sample

├── api

│ ├── handler

│ │ ├── admin.go

│ │ └── user.go

│ ├── main.go

│ ├── middleware

│ │ ├── auth.go

│ │ └── cors.go

│ └── views

│ └── errors.go

├── bin

│ └── main

├── config.json

├── docker-compose.yml

├── go.mod

├── go.sum

├── Makefile

├── pkg

│ ├── admin

│ │ ├── entity.go

│ │ ├── postgres.go

│ │ ├── repository.go

│ │ └── service.go

│ ├── errors.go

│ └── user

│ ├── entity.go

│ ├── postgres.go

│ ├── repository.go

│ └── service.go

├── README.md

Entities

Entities are the core business objects that can be realized by functions. In MVC terms, they are the model layer of the clean architecture. All entities and services are enclosed in a directory called pkg . This is actually what we want to abstract away from the rest of the application.

If you take a look at entity.go for user, it looks like this:

pkg/user/entity.go

Entities are used in the Repository interface, which can be implemented for any database. In this case we have implemented it for Postgre, in postgres.go. Since repositories can be realized for any database, therefore they are independent of all of their implementation details.

pkg/user/repository.go

Services

Services include interfaces for higher level business logic oriented functions. For example, FindByID, might be a repository function, but login or signup are service functions. Services are a layer of abstraction over repositories by the fact that they do not interact with the database, rather they interact with the repository interface.

pkg/user/service.go

Services are implemented at the user interface level.

Interface Adapters

Each user interface has it’s separate directory. In our case, since we have an API as an interface, we have a directory called api.

Now since each user-interface listens to requests differently, interface adapters have their own main.go files, which are tasked with the following:

Creating Repositories

Wrapping Repositories inside Services

Wrap Services inside Handlers

Here, Handlers are simply user-interface level implementation of the Request-Response model. Each service has its own Handler. See user.go
['Angad Sharma']
['Software Architecture', 'Go', 'Development', 'Clean Architecture', 'Technology']