Clean Architecture: Notes Backend in Node - Typescript
Tags: webdev, typescript, tdd, cleancode
Published: 2023-09-18 08:48:10



> # I hate complicated code! 😠
>
>  _But do you know what I <u>absolutely despise</u> ~~from the depths of my cold, black heart~~ ?_
>
>
>  _" Needlessly Complicated Code "_ - That is the worst !! 🤬 
> 
>  **An abomination of the highest order, I tell you !!!**

<br/>
So, you can imagine the horror of me seeing my codebase mutate into a quagmire
 of interconnected code segments, i.e. <u> files with a needlessly long list of dependencies that would break if I even looked at them the wrong way</u> .**It was a mess !!**
<br/>

So, what did I do next? I started researching **Software Architecture**.
I was looking for something that would produce decoupled code and give the added advantage of helping us migrate to <u>microservices</u> , if the need arose.

> Long story short, I decided to go with *Clean Architecture*
> <br/>
> Why you ask? Well, you can read it all about here : <u>_[Embracing Clean Architecture: A Journey to Better Code](https://www.chiranjeevthomas.com/article/embracing-clean-architecture-a-journey-to-better-code-at-dev-referral)_</u>

<br/>
<br/>
# Let's now look into the fundamentals of Clean Architecture before trying to implement it for a simple Notes App
<br/> 
( Why a simple notes app? Cause, understanding clean architecture is hard enough … If we add more complexity, it would end up being incomprehensible for someone getting introduced to clean architecture for the first time ) 
<br/>

<u> Clean Architecture stands on the following pillars: </u>
1. 1️⃣ Inversion of Control ( Dependency Inversion )
3. 2️⃣ Separation of Concerns ( Software Divided into layers - Presentation, Data, Application, Domain ) 
5. 3️⃣ One-way flow of data ( From the outer layer to the inner layer, with the inner layers knowing nothing about the outer layers)

\* \* You can read about Clean Architecture in detail on : <u>_[Uncle Bob's Website ](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)_</u>
<br/>
# <u> _I found this to be the simplest way to visualise Clean Architecture_ </u>
( WHAT'S GREAT ABOUT THIS PICTURE IS THAT YOU CAN DIRECTLY TRANSLATE IT TO CODE )
<br/>
<img src="https://res.cloudinary.com/dde6rnocj/image/upload/v1694768114/clean_architecture_ce31e2e471.png" width="800" height="800" />
```
main.ts
```
<img src="https://res.cloudinary.com/dde6rnocj/image/upload/v1694850829/main_5e6f5bf16f.png" width="800" height="800" />
<br/>
<br/>
<br/>
# <u>**A look at our Project`s Directory Structure :**</u>
```
/src
│── main.ts
│── server.ts
│── presentation
│ └── routers
│ └── notes-router.ts
├── domain
│ ├── interfaces
│ │ ├── repositories
│ │ │ └── notes-repository.ts
│ │ └── use-cases
│ │ └── notes
│ │ ├── create-note-use-case.ts
│ │ ├── delete-note-use-case.ts
│ │ ├── get-all-notes-use-case.ts
│ │ ├── get-one-note-use-case.ts
│ │ └── update-note-use-case.ts
│ ├── models
│ │ └── note.ts
│ ├── repositories
│ │ └── notes-repository.ts
│ └── use-cases
│ └── notes
│ ├── create-note.ts
│ ├── delete-note.ts
│ ├── get-all-notes.ts
│ ├── get-one-note.ts
│ └── update-note.ts
└── data
 ├── interfaces
 │ └── data-sources
 │ ├── nosql-database-wrapper.ts
 │ └── note-data-source.ts
 └── data-sources
 ├── mongodb
 └── mongodb-notes-data-source.ts
 
```
# <u>Let's start with our first use case test</u> : [ _Create Note_ ]
(Observe how few dependencies we have in our test file )
![create-note-test.png](https://res.cloudinary.com/dde6rnocj/image/upload/v1694851280/create_note_test_c2c3c5b44a.png)
<br/>

> ### In each Test File, we are going to test the implementation of a <u>Single Unit of Test ( SUT )</u>, and are going to <u>mock all the related dependencies </u>
> <hr/>
> So in the case of the *create note use case* our <u>SUT</u> is the implementation of the *create note use case interface ,i.e : the <u>CreateNote class</u>* , and we have a **single dependency** to mock : <u> _NotesRepository_ </u> 
> <hr/>

<br/>

<p>
When we try to execute this file, we'll encounter failure immediately, as nothing has been implemented as yet!
That's great, and it's by design … as we'll be practising the <u>TDD</u> way of doing things. 
<br/>

The great thing about following Clean Architecture is that it allows you to apply TDD practices from the get-go and in a very convenient way.
The whole system of Clean Architecture promotes <u>separation of concerns</u> and <u>dependency injection</u>, which are great for testing, as mocks can be easily created and injected into a <u>SUT</u>
</p>
<br/>
<br/>

# So, let's get started by defining the <u>CreateNotesUseCase </u> Interface
![create_note_use_case.png](https://res.cloudinary.com/dde6rnocj/image/upload/v1694849832/create_note_use_case_fbedbec188.png)
<br/>

Now, we observe that we need to define 2 more types to work with the Create Note Use Case Interface. 
<br/>

These 2 types, namely the **NoteRequestModel** and **NoteResponseModel** describe the _format_ of the input data that are supplied to the CreateNoteUseCase's execute method and the format of the data we'll get in response to saving it to the <u>Database</u> using the <u>NotesRepository</u> abstraction. 
<br/>

## Let's quickly define these 2 types :

![create_note_use_case_types.png](https://res.cloudinary.com/dde6rnocj/image/upload/v1694850642/create_note_use_case_types_3521540a36.png)

<br/>

<p>
Great, now we need to mock our singular dependency for the create note use case : ( NotesRepository ) 
<br/>

The NotesReposity interface would provide the methods to <u>CREATE</u>, <u>READ</u>, <u>UPDATE</u> and <u>DELETE</u> notes.
<br/>


Let's define the NotesRepository interface before mocking it : 

</p>
![notes_repository.png](https://res.cloudinary.com/dde6rnocj/image/upload/v1694852459/notes_repository_5f08746e8c.png)
<br/>

<br/>
## Finally , it's time for us to create the <u>NotesRepository mock</u> , and a <u>helper</u> function called <u>getMockNotesRepository</u>
![mock_notes_repository.png](https://res.cloudinary.com/dde6rnocj/image/upload/v1694853227/mock_notes_repository_c9a9f3dcbd.png)

## Another helper required to run our test :
![expectedNotesOutput.png](https://res.cloudinary.com/dde6rnocj/image/upload/v1694858720/expected_Notes_Output_a5eda43dfd.png)
<br/>

<br/>
## Now, we need to define our SUT ( the concrete implementation of the CreateNoteUseCase )
![create-note-impl.png](https://res.cloudinary.com/dde6rnocj/image/upload/v1694853566/create_note_impl_622291f7a3.png)
<br/>

<br/>
<bold> With all the setup done, we can finally go ahead and run our test! </bold>
<br/>
![create-note-test.png](https://res.cloudinary.com/dde6rnocj/image/upload/v1694851280/create_note_test_c2c3c5b44a.png)
<br/>
## And, we get a passing test :
<br/>
![Screenshot 2023–09–16 at 2.21.05 PM.png](https://res.cloudinary.com/dde6rnocj/image/upload/v1694854326/Screenshot_2023_09_16_at_2_21_05_PM_2dfbc63dcb.png)

<br/>
What's next? Well as an assignment, go ahead and try to implement the rest of the use cases ( <u>DeleteNoteUseCase</u>, <u>UpdateNoteUseCase</u>, <u>GetNotesUseCase</u>, <u>GetOneNoteUseCase</u> ). 


## Do follow the same TDD methodology while implementing your tests


---


# We'll meet again and test the NotesRepository, till then … Adios !!

---

You can view the complete code and the repository with all test cases implemented over here: <u> **[GutHub Repo](https://github.com/DevReferral/clean-architecture-notes-typescript-tdd/tree/main)** </u> 
<br/>


---

My blog is inspired by a number of other blogs on the same subject, which are as follows :

1 . [Clean Architecture Contacts](https://nanosoft.co.za/blog/post/clean-api)
2 . [Clean Architecture Fundamentals ](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)
3.[TDD Fundamentals ](https://www.codurance.com/katas/fizzbuzz)

---

[The blog was first published here]:(https://www.chiranjeevthomas.com/article/clean-architecture-building-a-notes-app-backend-in-node-express-typescript)