Clean Code Architecture in Go
Tags: go, architecture, cleancodearchitecture
Published: 2020-04-05 14:40:57

---
title: Clean Code Architecture in Go
published: true
description: My personal opinion on the Clean Code Architecture in the context of Domain Driven Design (DDD), yet i adopted some terms from the Onion Architecture such as domain to avoid any misleading interpretations with the Entity in DDD
tags: #go #architecture #clean-code-architecture
---

Everyone can write code to produce a software that functionally works as expected, yet not everyone care about how's their code architecture look like. The best chosen algorithms not always save us from the bad software design. There are many code architectures around, and recently i've been struggling and trying to promote the [Clean Code Architecture](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html) from Robert C. Martin a.k.a. [Uncle Bob](http://cleancoder.com/products). Let's start with how this sort of code architecture looks like in [Go](https://golang.org/). 

I’m gonna start by implementing some of the functionalities within a shopping cart since it’s pretty straightforward. Bear in mind that what i’ll be showing here is restricted to the _bounded context_ of the shopping cart, means we’ll just focus with the process of how a user/buyer choose the item and adding that particular item into his cart, and subsequently continue with the checkout. As for the billing/payment part, that will be in the _bounded context_ of another service such as payment service. (if you’re neither really familiar nor confidence with what _bounded context_ is, i would suggest you to read another article of mine from [here](https://medium.com/@yauritux/ddd-part-i-introduction-cabab1d2e27d).

By the way, all of the source code i explain here can be cloned/forked from {% github https://github.com/yauritux/clean-code-architecture no-readme %}

![Common Shopping Cart Process](https://dev-to-uploads.s3.amazonaws.com/i/cfgza08oi41iq9ke9us0.jpg)

What are highlighted in the grey colors were standing outside of our shopping cart _bounded context_. Hence, we won’t tackle the nitty gritty details of those objects within our code implementation since those things would be in other services (e.g. **product catalogue service** and **user service**). Nevertheless, we’ll still be having those objects within our code, in the _context_ of what our shopping cart needs. For instance, we won’t need user credentials information in our shopping cart since that should be catered from the **user service** context. Basically, we just need user information which is related to the shopping cart itself, such as: **user_session_id**, **shipping address**, **billing address** (furthermore, address information should also be catered from another service, e.g. : **address service**, even this is also optional).

There are some rules for this architecture those we must bear within our mind. I've summarized those rules as following: 
1. Dependency between layer should be going inward in one direction. As far as i concern, it was designed like this to avoid any [circular dependencies](https://en.wikipedia.org/wiki/Circular_dependency).
2. A layer should depend only on one direct layer (one level) beneath it, it shouldn’t know any layers beyond that level. For instance, **A** depends on **B** ( **A → B** ), and **B** depends on **C** ( **B → C** ), yet **A** shouldn’t know anything about **C**.
3. Each layer should depends upon abstraction ( interface ) rather than implementation. This complies with what **Uncle Bob** said about 2 rules to fix **RFI** issues, you can read it from my old article [here](https://yauritux.wordpress.com/2011/04/03/history-of-dependency-injection-di/).

Let’s jump to the implementation by creating our project folder from the terminal and also initialize the go module as shown below:

```
mkdir cart-service && cd cart-service
go mod init github.com/yauritux/cart-svc
```

Next step is creating our `pkg` directory (`mkdir pkg`) from the same terminal. This `pkg` directory will contain our implementation logic for the **shopping cart** which complies with the **clean code architecture** we’re discussing here.

By referring to the depicted shopping cart process diagram earlier, we’ll be having these following **entities** within our code:
1. **User** (this also represents a **Buyer** in the **shopping cart** _bounded context_).
2. **Cart** (as the name implies, this is our cart object which holds our shopping items).
3. **Product** (used as a placeholder for the product information. And for the sake of simplicity…, we won’t have any product categories because our goal here was merely to discuss the Clean Code Architecture).

I create those 3 **entities** within my `pkg/domain/entity` folder. To keep it simple, i deliberately marked all of the fields as _exported fields_ (moving forward, we can think about hiding the fields information behind the _setter_ / _getter_ which are commons in **Java**).

`Cart Entity`:
{% gist https://gist.github.com/yauritux/7d252b18def3c6ebc47802974223ac04 %}

`User Entity`:
{% gist https://gist.github.com/yauritux/95be7c8902156f6ffa5a1065d69d4963 %}

`Product Entity`:
{% gist https://gist.github.com/yauritux/c86025739aef3da15aab93684cc5c7d1 %}

And here our **value objects** ( `pkg/domain/valueobject` ):
1. **Cart Items** (strongly related to **Product** entity).
2. **Buyer Address** (comprises of **Billing** and **Shipping addresses**, determined by the _Address Type_).

`CartItem Value Object`:
{% gist https://gist.github.com/yauritux/4f58b2242bb59ac13a2a2858849c12ac %}

`BuyerAddress Value Object`:
{% gist https://gist.github.com/yauritux/5a1a78d5090df11a135c867d8ec83752 %}

Additionally, we will also have our **enums** as shown below:

{% gist https://gist.github.com/yauritux/8081fac6613da0a7e7deadd04be27242 %}

{% gist https://gist.github.com/yauritux/dc1ffc73db15356fa00bfdb98c8cb5fe %}

If you’re wondering about the differences between entities and value objects, you can read it from {% medium https://medium.com/@yauritux/ddd-part-ii-b0735ba584ca %}.

The next important thing to do is to implement our core business logic, which is part of **Entities** in **Clean Code Architecture**, or **Core Domain** in terms of [Onion Architecture](https://www.thinktocode.com/2018/08/16/onion-architecture/). This is something that is related to the enterprise business rules out of the application service rule.

In order to implement this kinda thing, we need to setup our **aggregate root** (i call it as **user_cart aggregate**). Again, take a look at what i wrote [here](https://medium.com/@yauritux/ddd-part-ii-b0735ba584ca) if you’re still wondering about what is the aggregate all about.

{% gist https://gist.github.com/yauritux/f275baf2b88d647a5773b52e82d4e0d4 %}

Another to-do thing is to setup our **repositories**. Bear in mind, that when we’re talking about repository, it’s not always about the **database**. The storage implementation could be anything such as: **web services**, **file**, **in-memory**, etc.., and they should be abstracted by following some contracts defined on the interface. In that way, we can use them interchangeably later since we make our client code depends on the interface rather than directly on the implementation. In order to make it possible, we should start by abstracting our **repositories** with **interfaces** such as following:

`Cart Repository Interface`:
{% gist https://gist.github.com/yauritux/c70111df76b1ced2302409488129b89c %}

`User Repository Interface`:
{% gist https://gist.github.com/yauritux/081d83cec2a09f44c518af8041a36c5e %}

`Product Repository Interface`:
{% gist https://gist.github.com/yauritux/ef1c3b56587aa8b0562e46f5413c3b89 %}

I would assume that some of you will be asking about those **empty interfaces** :-). Why do they exist ? Why do we use them ?.

As far as i concern, we’ll be having different models for every layer in order to make our architecture more loosely-coupled. In that case, we should abstract our interface model as far as we can, thus we can have more flexibility within our code. Let’s say for the user repository interface, we can have 2 implementations for it, one implementation to get the user information from the database, and another one to get the information from a web service (e.g. REST). Therefore, definitely we’ll have 2 models here, one based on the database model, and another one is based on the web request-response model. That’s the reason why we use **empty interface** ( `interface{}` ) within our repository interface. You get it right ? :-). Don’t worry, everything will become clear once we implement our interface.

For the sake of simplicity, we'll be implementing just **in-memory repository** for now since our first goal is merely to discuss about how’s our clean code architecture will be looked like. However, i will incrementally update the code later for another kind of storage / repository, such as database or web service.

Let’s start to implement our repository interface by creating another directory (at the same level with our `domain` directory) as shown below:

```
mkdir -p pkg/adapter/repository/inmem/model
```

And here are our models (inside the `pkg/adapter/repository/inmem/model` directory) to be used in the context of our **in-memory repository** (remember about the `interface{}` before, when we designed our repository contract interface).

`User Model for In-Memory Repository Implementation`:
{% gist https://gist.github.com/yauritux/2499353683fd3db9ad1dbefb331fb5c0 %}

`Cart Model for In-Memory Repository Implementation`:
{% gist https://gist.github.com/yauritux/0dbfa0f6825c25138db68355adb56f0e %}

`Product Model for In-Memory Repository Implementation`:
{% gist https://gist.github.com/yauritux/80751f9ac0f12438230707d6a40f0436 %}

subsequently followed by our in-memory repository implementation for those 3 models respectively (inside `/adapter/repository/inmem directory`):

`User In-Memory Repository Implementation`:
{% gist https://gist.github.com/yauritux/0dc3b473a5a76e1ce6ad8b8376a21275 %}

`Cart In-Memory Repository Implementation`:
{% gist https://gist.github.com/yauritux/1fa65828558cf705003090be302a1fba %}

`Product In-Memory Repository Implementation`:
{% gist https://gist.github.com/yauritux/407f97637f6b1246c08d9e8f1e726c49 %}

And the _use cases_ for **cart** and **user** as written below :

`User Usecase Port`:
{% gist https://gist.github.com/yauritux/b273762f2706c8933b52ac1b4e2dfc33 %}

`User Usecase Interactor`:
{% gist https://gist.github.com/yauritux/88be7357b163fe4e68389780fc07a1bd %}

`Cart Usecase Port`:
{% gist https://gist.github.com/yauritux/3237ca69ef5dfc9cd1563795be33f871 %}

`Cart Usecase Interactor`:
{% gist https://gist.github.com/yauritux/50423f64c021290e9eef47a7be4dc516 %}

`Product Usecase Interactor`:
{% gist https://gist.github.com/yauritux/50423f64c021290e9eef47a7be4dc516 %}

Last but not least, let’s create a small CLI program to test our shopping cart functionalities that we’ve created so far.

`Shopping Cart CLI tester using in-memory repository`:
{% gist https://gist.github.com/yauritux/4911d393f4d5139a89f4d58ac5b3b67b %}

Ok, some of you might get overwhelmed with all of the code here (while some of you might not), especially in regards with the **use case port** and **interactor** (what would be the difference between those 2).

Test our CLI by using this following command from the terminal:

```
go run cmd/cli/main.go
```

You can grab the full code from [here](https://github.com/yauritux/clean-code-architecture)

Let me know for any concerns and/or questions from you guys :-).