# Build an ExpressJS Application With Clean Architecture

## Motivation

Similarly to my [Front-End implementation](https://morintd.hashnode.dev/build-a-react-application-with-clean-architecture), I'm not satisfied with the available resources related to Clean Architecture. That's right, even on the Back-End!

## What is Clean Architecture

If you stumbled upon this article, you probably know about Clean Architecture, but are looking for more information.

In the rare event of a beginner reading this article, I highly recommend getting started with the [necessary theory](https://blog.scalablebackend.com/understand-the-theory-behind-clean-architecture).

## What are we going to build

While I wrote this article, my goal was to test if Clean Architecture was as flexible as it promised. That's the reason I re-used the same entities and use cases as my Front-End implementation, and tried to move the infrastructure part to the Back-End with Express.

That means, the application is the same: a Tic-Tac-Toe game (in TypeScript). You will be able to send requests to a Back-End and play a complete game.

If you want to follow along with me, you can clone my [starter project](https://github.com/morintd/expressjs-tic-tac-toe-clean-architecture/tree/original).

### Behaviors

You can find the Front-End Tic-Tac-Toe on [CodeSandbox](https://codesandbox.io/p/sandbox/react-dev-q2z497) to understand what the application is doing in practice. There are two main functionalities:

* Obviously, you can play a game of Tic-Tac-Toe.
    
* You can go back to a previous move (history) and play again.
    

Instead of being a Front-End application, we will provide endpoints with the same behavior.

### File Structure

The original application already follows the idea of Screaming Architecture, with three directories:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1710438717844/fa7785f1-80ab-48c1-8207-d64b074b2b42.png align="center")

* `common/` includes all the shared source code.
    
* `core/` defines the entry point of our application:
    
    * `app.ts` contains the ExpressJS server.
        
    * `bootstrap.ts` uses the code inside `app.ts` to build a server and listen to it.
        
* `tic-tac-toe/` contains everything related to the game itself.
    

### Files

While you can have a look at the entire project by yourself, please note there are three main files:

**App**

%[https://gist.github.com/morintd/a515410c627067ba659f74084fad9554] 

`createApp` is responsible for building the ExpressJS server and uses the Tic-Tac-Toe module (which is responsible for routing but is not the focus of this article).

**Tic-Tac-Toe Controller**

%[https://gist.github.com/morintd/e2e0ddc9d1ab7c17ace80ddf7178ae92] 

`TicTacToeController` is responsible for handling requests. It's the one that contains the business logic and the core part of the original implementation.

**Board Service**

%[https://gist.github.com/morintd/a3c7628c0cf8fa6a39ddda1a4c945dbc] 

`BoardService` takes the role of a data access object, which is an in-memory implementation for simplicity.

### Define a Game Model

Similarly to my Front-End implementation, I like to start by defining a clear *Domain Model*. Its goal is to define the elements that make up our system. Please, keep in mind this is not strictly a part of Clean Architecture but [Domain-Driven-Design](https://en.wikipedia.org/wiki/Domain-driven_design).

For our game of Tic-Tac-Toe, we need:

* A board composed of 9 squares.
    
* Players and winners.
    
* At one point in time, the state of our game:
    
    * Is there a winner?
        
    * The history of moves (so we can navigate among them).
        
    * Who is playing next?
        
    * Potentially, the index of the last game played.
        

I'll create this file under `tic-tac-toe/`, using a namespace to make it clear:

%[https://gist.github.com/morintd/74deed0f78ccb88678e9b576ebeaa0ec] 

### Create the base structure for Clean Architecture

We will create an **entity** and **use case** in a minute. We can create the base classes for them under `common/`:

%[https://gist.github.com/morintd/8f340c0c36f992e6d94e4602a813a2dd] 

%[https://gist.github.com/morintd/5ca3d34ac252e845050fe835051b7058] 

Keep in mind:

> There are multiple ways to define those.
> 
> For `Entity`, I like to store properties inside a `_data` object and make it protected. It prevents developers from mutating it directly, which is a common source of issues. Depending on our needs, this class will definitely change.
> 
> There are multiple practices when it comes to **use cases**, but a very common one is to provide an `execute` method, which returns a `Promise` most of the time.

### Create the Board Entity

Most of the logic of the Tic-Tac-Toe game seems related to the state of the *board*. Let's create an entity for it, inside a new `entities` subfolder, under `tic-tac-toe`:

%[https://gist.github.com/morintd/775f3fffb283278bc84efa33270c77bc] 

Here:

* We store squares, based on the types from our `GameDomainModel`.
    
    * We add a getter to easily access the property.
        
* We already have the formula to calculate if player **X** plays next.
    
    * We copy it from the `TicTacToe` file inside the starter project.
        
    * We can calculate the current step based on the filled squares.
        
* The entity is also a great place to calculate if there is a winner.
    

We can also copy the formula from the starter `TicTacToeController` file.

In "Clean Architecture", Uncle Bob says:

> An Entity is an object within our computer system that embodies a small set of critical business rules operating on Critical Business Data.

In our context, our critical business rules are the rules of the game of Tic-Tac-Toe.

### Starting with our first use case

Now, we have everything we need to create an empty **use case**. We can get started with an obvious one, playing a move.

Obviously, it will take the *square* we play on. On the other hand, we also need to define the *step* we play on, as we can play on a previous move. Our **use case** will probably return an object similar to the game state:

%[https://gist.github.com/morintd/f2ab8c5ea3fd876c1aac80daff9f1d9c] 

> We could probably use `GameDomainModel.GameState` as `Output` here. On the other hand, those objects may only seem familiar, and change for different reasons.

To be honest, the current code inside `TicTacToeController` is very similar to the future content of the `Play` use case. It might be because I created this project as another implementation, but the original project is still far from using Clean Architecture.

If you remember well, a use case shouldn't depend on a data access gateway from the Interface Adapters layer.

### Add the board repository

Instead of the current `BoardService`, I'll define an interface as a `port` and its implementation will be an `adapter`. I'll also use the definition of `Repository` instead of `Service` for consistency.

Let's start with the interface by creating a sub-directory `ports/` under `tic-tac-toe/`, with a file called `board-repository.port.ts`:

%[https://gist.github.com/morintd/121381bcd270a0c7385b5affdf0d1367] 

Then, we can create an `adapters/` sub-directory under `tic-tac-toe/`. Also, the previous `BoardService` shouldn't be called `BoardRepository`.

It's not ***the*** implementation of IBoardRepository, it's one among others. To be more precise, it's an in-memory implementation.

Let's create `in-memory-board.repository.ts`:

%[https://gist.github.com/morintd/2bafcff1026a6dac5dc4e11e3ff7880b] 

Before we go back to our **use case**, we need one more thing: **exceptions**.

### Exception management

If you look at the original `TicTacToeController`, you can see we throw exceptions when:

* The step we are supposed to play on doesn't exist
    
* We play on a square that's already taken
    

With Clean Architecture, we cannot throw exceptions that belong to the infrastructure layer (Interface Adapters & Framework and Drivers), from the use case layer.

Instead, we need to throw a Domain Exception, that is handled by the controller.

Let's define two **exceptions**, stored inside an `exceptions/` sub-directory (itself inside `tic-tac-toe/`):

%[https://gist.github.com/morintd/97df4bd51bb88108d6c113db54962e66] 

%[https://gist.github.com/morintd/53a5069746b8a19026b105a2b780c6f9] 

### Complete our use case

Now that we have our **entity**, **repository**, and **exceptions**, we can complete our **use case**. Most of the logic can be transferred from `TicTacToeController`, in `handlePlay`.

There are a few changes necessary:

* Business rules are now inside the `Board` entity.
    
* We rely on the `IBoardRepository`.
    
* We throw a Domain Exception
    

%[https://gist.github.com/morintd/5ec5f5108ab60c8ff90773230d92330b] 

This use case was added under `tic-tac-toe/` in its own sub-directory `use-cases/`.

### Adding missing use cases

The process is similar for the two other use cases. We can retrieve most of the logic from the `TicTacToeController` but use our brand new `Board` entity and `IBoardRepository`.

Let's start with `jump-to.use-case.ts`:

%[https://gist.github.com/morintd/fee43fcd743fb35543729c3223667376] 

Then, we can add `initialize.use-case.ts`, which is responsible for starting a new game:

%[https://gist.github.com/morintd/218074efa54f7f86552ec870fee1f581] 

### Binding use cases to a controller

The last part is definitely way easier in a Back-End environment. We simply need to:

* Execute the right use case
    
* If there is a Domain (or unknown) Exception, throw the related Application Exception
    
* Otherwise, return the result with the right status code.
    

%[https://gist.github.com/morintd/00c707c1d979a181adaa07a81e3236ff] 

### Dependency Injection

Same thing here, using dependency injection is definitely easy. Depending on the Back-End framework you're using, you will have different solutions (or you can setup your own with [InversifyJS](https://inversify.io)).

In this example, I manually instantiate and inject dependencies from `app.ts`:

%[https://gist.github.com/morintd/334d908818d0d44e07aaa681c97df808] 

### Using a presenter

If you look closely at our current controller, it's doing more than orchestration. It's also formatting data for `moves`, `status`, and `squares`, which is not really its role.

A better architecture would use a presenter instead. There are multiple ways to define a presenter. A common practice is to define a class with a `format` method.

Let's create `presenter.ts` inside `common/`:

%[https://gist.github.com/morintd/343b76ce8e7f2df2167840ef97642b82] 

Now, we need to define our actual **presenter**. It's supposed to present our game and return the related `squares`, `moves`, and `status`. Based on our current code, it needs the current `history`, `winner`, `xIsNext`, and `step`.

> A controller shouldn't depend directly on a presenter but on its interface.

Let's create a `game-presenter.port.ts` inside `tic-tac-toe/ports/`:

%[https://gist.github.com/morintd/7ad03c9f530a28f85b113efa0f240547] 

Now, we can add the implementation, as `game.presenter.ts` inside `tic-tac-toe/adapters/`:

%[https://gist.github.com/morintd/23d5d88f269f4343557a25fcb081d80b] 

### Completing controller

Now, we can expect our `IGamePresenter` inside the `TicTacController` constructor (which we instantiate and inject from `app.ts`). Then, we can remove the method related to formatting and instead use the presenter:

%[https://gist.github.com/morintd/2217cabc6a3244135a71fb8769a54956] 

## Conclusion

Your Back-End Tic-Tac-Toe game is now fully functional, and adheres to Clean Architecture! The domain (logic) is completely isolated from the infrastructure.

Feel free to look at the [end result](https://github.com/morintd/expressjs-tic-tac-toe-clean-architecture).

You would have no problem moving away from ExpressJS and using another Back-End framework like Fastify or NestJS. If you did, you wouldn't need to modify any code that's part of the domain layer.

Not only could you use another Back-End framework, but you could even make this game a [Front-End application](https://morintd.hashnode.dev/build-a-react-application-with-clean-architecture)!
