Clean Architecture on Frontend

What clean architecture is, what it is useful for and how to use it on frontend.

Hello World! 👋

My name is Alex.

I am a developer, mentor, and speaker.

System Design

Designing is fundamentally about taking things apart... in such a way that they can be put back together. ...Separating things into things that can be composed that's what design is.

Rich Hickey Design. Composition and Performance

Clean Architecture

Functionality is split in three layers: domain, application, and adapters

Dependencies Rule

External layers can depend on internal but not otherwise

Advantages

Costs

How to Manage Costs

Most important:

Live Design!

Sample app — online cookie store Example of the store cart

Starting From?..

Empty diagram with infrastructure-UI split

Domain Layer

Domain will contain entities for user, product, cart, and order. Also it will contain the code for their data transformations

Application Layer

Application layer contains user scenarios, a.k.a use cases

Adapters Layer

Adapters contain modules for messaging with the outer world

User Entity and Domain Type

Domain User Type
export type UserName = string;
export type User = {
    id: UniqueId;
    name: UserName;
    email: Email;
    preferences: Ingredient[];
    allergies: Ingredient[];
};

Product and Cart Entities and Types

Product domain type Cart domain type
export type ProductTitle = string;
export type Product = {
  id: UniqueId;
  title: ProductTitle;
  price: PriceCents;
  toppings: Ingredient[];
};
export type Cart = {
  products: Product[];
};

Order Entity and Domain Type

Order domain type
export type OrderStatus =
    "new" | "delivery" | "completed";
export type Order = {
    user: UniqueId;
    products: Product[];
    created: DateTimeString;
    status: OrderStatus;
    total: PriceCents;
};

Domain Interaction

How domain entities interact with each other

Data Transformations

Shared Kernel

type Email = string;
type UniqueId = string;
type DateTimeString = string;
type PriceCents = number;
        

Checkout Use Case

In the application layer we create use cases like checkout, authentication etc

Impure Context for Functional Core

Impure functions can only call pure functions

Checkout Use Case

type OrderProducts = (user: User, cart: Cart)
    => Promise<void>

Application Ports

Use Case Flow Check

Uwe case works as expected

Design Adapters

Flow Diagram

Final diagram of user accessing the application functionality

Feature Slice

Feature slice as a piece of hexagonal pie

What About OOP?

The generated tree image

Sources

Alex Bespoyasov 👋