# Minitalk
## Web Application Architecture
### 07/02/2020
[`@pereirazc`](https://github.com/pereirazc/buckpal)
---
#### Many layers of bad practices

---
#### Database-driven development
Why are we making the **database** the foundation of our architecture and not the **domain logic**?
---
#### Basic

---
#### Layer shortcuts

---
#### Fat Services

---
## Let's clean it up :shower:

**Alistair Cockburn**

**Robert Martin aka "Uncle Bob"**
---
## Let's clean it up :shower:

by Robert C. Martin
---
### Hexagonal Architecture

---
### Clean Architecture

---
### Reponsabilities of the Controller Adapter
* Map HTTP request to objects
* Perform **authorization** checks
* Validate input
* **Map input to the input model of the use case**
* **Call the use case**
* Map output of the use case back to HTTP
* Return HTTP response
---
### Responsabilities of an Use Case
* Take input
* **Validate business rules**
* Manipulate model state
* Return output
---
### Responsabilities of Persistence/DB Adapter
* Take input
* **Map input into database format**
* Send input to the database
* Map database output into application format
* Return output
---
## Hands On

---
#### Hands On - Transfer money :money_with_wings:

---
#### Architectural Overview

The web controller calls an incoming port, which is implemented by a service. The service calls an outgoing port, which is implemented by an adapter.
---
#### *SendMoney* Use Case

A service implements a use case, modifies the domain model and calls an outgoing port to persist the modified state.
---
#### AccountController
```java
public class AccountController {
private final SendMoneyUseCase sendMoneyUseCase;
...
@PostMapping(path = "/accounts/sendMoney/{sourceAccountId}/{targetAccountId}/{amou\
nt}")
void sendMoney(
@PathVariable("sourceAccountId") Long sourceAccountId,
@PathVariable("targetAccountId") Long targetAccountId,
@PathVariable("amount") Long amount) {
SendMoneyCommand command = new SendMoneyCommand(
new AccountId(sourceAccountId),
new AccountId(targetAccountId),
Money.of(amount));
sendMoneyUseCase.sendMoney(command);
...
}
...
}
```
---
#### SendMoneyCommand
```java
public class SendMoneyCommand {
private final AccountId sourceAccountId;
private final AccountId targetAccountId;
private final Money money;
public SendMoneyCommand(...)
```
---
#### Account
```java
public class Account {
private AccountId id;
private Money baselineBalance;
private ActivityWindow activityWindow;
public Money calculateBalance() ...
public boolean withdraw(Money money, AccountId targetAccountId) ...
public boolean deposit(Money money, AccountId sourceAccountId) ...
}
```
---
#### SendMoneyService
```java
public class SendMoneyService implements SendMoneyUseCase {
private final LoadAccountPort loadAccountPort;
private final AccountLock accountLock;
private final UpdateAccountStatePort updateAccountStatePort;
public boolean sendMoney(SendMoneyCommand command) {
// validate business rules
// manipulate model state
// return output
}
}
```
---
#### Account Repository vs. Exclusive Ports
**OK**

Centralizing all database operations into a single outgoing port interface makes all services depend on methods they don’t need.
---
#### Account Repository vs. Exclusive Ports
**BETTER**

Applying the Interface Segregation Principle removes unnecessary dependencies and makes the existing dependencies more visible
{"metaMigratedAt":"2023-06-15T04:06:14.423Z","metaMigratedFrom":"YAML","title":"Minitalk - Web Application Architecture","breaks":true,"image":"https://www.locaweb.com.br/images/open-graph.jpg","slideOptions":"{\"theme\":\"back\",\"transition\":\"slide\",\"spotlight\":{\"enabled\":true}}","contributors":"[{\"id\":\"f68e4433-ed93-4564-a6f2-82501df0c6ce\",\"add\":6920,\"del\":2317}]"}