<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="/feeds/atom-style.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://fres.space/</id>
    <title>Francesco Calicchio</title>
    <updated>2026-02-01T20:55:56.090Z</updated>
    <generator>Francesco Calicchio's Blog Feed Generator</generator>
    <author>
        <name>fres</name>
        <uri>https://fres.space</uri>
    </author>
    <link rel="alternate" href="https://fres.space/"/>
    <link rel="self" href="https://fres.space/atom.xml"/>
    <subtitle>I am a Software Engineer from Italy 🇮🇹 passionate about building application of every kind, from web to mobile and beyond. I love to learn new technologies and share my knowledge with others. In my free time, I enjoy hacking stuffs, cycling and geopolitic.</subtitle>
    <rights>Copyright © 2026 fres</rights>
    <entry>
        <title type="html"><![CDATA[How to use Bloc effectively]]></title>
        <id>https://fres.space/posts/bloc-pattern/</id>
        <link href="https://fres.space/posts/bloc-pattern/"/>
        <updated>2026-02-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Learn how to use Bloc effectively in a Flutter application.]]></summary>
        <content type="html"><![CDATA[<h2>How to use Bloc effectively</h2>
<p>Bloc is a very widely used state manager in the Flutter community, but during my career I've seen many developers using it in a wrong way and the documentation is not very clear about how to use it effectively and how to architect a good application using Bloc.</p>
<p>In this article I'll try to explain <strong>my</strong> way of using Bloc to manage state in a Flutter application.</p>
<h2>What is Bloc?</h2>
<p><strong>Bloc</strong> (Business Logic Component) is a state management pattern that separates your app's business logic from the UI. It works by receiving events as input and emitting states as output, so the UI only listens to state changes and rebuilds accordingly. This keeps the code predictable, easy to test, and easy to maintain.</p>
<h3>Bloc vs Cubit</h3>
<p>The Bloc library contains not only the <code>Bloc</code> class and all its related helpers, but also the <code>Cubit</code> class.</p>
<p><strong>Cubit</strong> is a simpler, lighter alternative to Bloc. It's essentially Bloc without events: instead of emitting states in response to events, a Cubit exposes methods that you call directly, and those methods emit new states. Both Bloc and Cubit are part of the same <code>bloc</code> package and share the same underlying stream-based architecture.</p>
<p><strong>Main difference:</strong> Bloc uses events as input; Cubit uses method calls. That makes Cubit simpler and less boilerplate-heavy, while Bloc gives you a more traceable, event-based history that's useful for debugging and logging. Here's what that looks like in code.</p>
<p><strong>Bloc</strong> — events as input:</p>
<pre><code>// Events
sealed class CounterEvent {}
class IncrementPressed extends CounterEvent {}
class DecrementPressed extends CounterEvent {}

// Bloc: maps events → states
class CounterBloc extends Bloc&lt;CounterEvent, int&gt; {
  CounterBloc() : super(0) {
    on&lt;IncrementPressed&gt;((event, emit) =&gt; emit(state + 1));
    on&lt;DecrementPressed&gt;((event, emit) =&gt; emit(state - 1));
  }
}

// Usage
context.read&lt;CounterBloc&gt;().add(IncrementPressed());
</code></pre>
<p><strong>Cubit</strong> — methods as input:</p>
<pre><code>// Cubit: methods emit directly
class CounterCubit extends Cubit&lt;int&gt; {
  CounterCubit() : super(0);
  void increment() =&gt; emit(state + 1);
  void decrement() =&gt; emit(state - 1);
}

// Usage
context.read&lt;CounterCubit&gt;().increment();
</code></pre>
<ul>
<li><strong>When to use Cubit:</strong> Prefer Cubit for straightforward flows where you don't need event-level visibility (e.g. simple forms, local UI state).</li>
<li><strong>When to use Bloc:</strong> Use Bloc when you need event traceability, complex flows with many event types, or when debugging and logging events is important (e.g. analytics, undo/redo, or large features with many interactions).</li>
</ul>
<h2>Freezed and Equatable</h2>
<p>Now that we have a basic understanding of what Bloc is, let's talk about the libraries that will help with the definition of our states and events.</p>
<ul>
<li>
<p><strong>Freezed</strong> is a library that allows you to easily create immutable objects in Dart. It's a powerful tool that helps you manage states in your application.</p>
</li>
<li>
<p><strong>Equatable</strong> is a library that allows you to easily compare objects in Dart. It's a powerful tool that helps you manage state in your application.</p>
</li>
</ul>
<h3>Why use Freezed or Equatable?</h3>
<p>Bloc compares states with <code>==</code> to decide whether to notify listeners. If you use plain classes, two instances with the same data are treated as different (reference equality), so Bloc may emit "new" states that are logically unchanged and cause unnecessary rebuilds.</p>
<p><strong>Equatable</strong> fixes this by letting you compare objects by their fields. When two states have the same values, they're considered equal—Bloc won't emit again, and your UI won't rebuild needlessly. It also reduces boilerplate for <code>==</code> and <code>hashCode</code>.</p>
<p><strong>Freezed</strong> goes further: it generates immutable classes, <code>copyWith</code>, and often value equality as well. It excels at modeling states and events as union types (e.g. <code>Loading | Success(data) | Error</code>), so you get exhaustive pattern matching and clear, type-safe state definitions. Let's see the difference in code.</p>
<p><strong>Without Equatable</strong> — reference equality causes extra emissions:</p>
<pre><code>class UserState {
  final String name;
  UserState(this.name);
}
// UserState('Alice') != UserState('Alice')  → Bloc emits, UI rebuilds
</code></pre>
<p><strong>With Equatable</strong> — value equality prevents unnecessary rebuilds:</p>
<pre><code>class UserState extends Equatable {
  final String name;
  UserState(this.name);
  @override
  List&lt;Object?&gt; get props =&gt; [name];
}
// UserState('Alice') == UserState('Alice')  → no emit, no rebuild
</code></pre>
<p><strong>With Freezed</strong> — union types, immutability, and <code>copyWith</code> in one:</p>
<pre><code>@freezed
class UserState with _$UserState {
  const factory UserState.initial() = _Initial;
  const factory UserState.loading() = _Loading;
  const factory UserState.loaded(User user) = _Loaded;
  const factory UserState.error(String message) = _Error;
}
</code></pre>
<p>Together, they keep your states and events immutable, comparable by value, and easy to maintain, which aligns perfectly with Bloc's design and helps avoid bugs and performance issues.</p>
<h3>Why Immutability Matters for States and Events</h3>
<p>Immutability means that once an object is created, it cannot be changed. To represent a new state, you create a new object instead of modifying the existing one. This might seem like extra work, but it has profound benefits for state management.</p>
<ul>
<li>
<p><strong>Predictability and traceability.</strong> Each state is a snapshot in time. When something goes wrong, you can look at the state that was emitted and know exactly what the app was representing no hidden mutations after the fact. Bloc's event → state flow becomes a clear, auditable log: given these events, you get these states. With mutable objects, state can change from anywhere, at any time, making it nearly impossible to reason about what the UI was showing when a bug occurred.</p>
</li>
<li>
<p><strong>No shared mutable state bugs.</strong> When you pass a mutable object around, any widget, callback, or async operation can mutate it. Multiple parts of the codebase might read the "same" state while another part changes it, leading to race conditions, inconsistent UI, and bugs that only appear under certain timing. With immutability, once a state is emitted, it's frozen. Nobody can alter it. The only way to get a new state is for the Bloc to emit one—so there's a single, clear source of truth.</p>
</li>
<li>
<p><strong>Safe async and concurrent code.</strong> In async flows, mutable state can change between when you read it and when you use it. By the time a <code>Future</code> completes, the object you captured might have been modified. Immutable states eliminate this: the state you received is the state you have, forever. No one can change it from under you, which makes async logic much easier to reason about and debug.</p>
</li>
<li>
<p><strong>Easier testing.</strong> Immutable states and events are trivial to test. Create a state, pass it to a widget or validator, and it never changes. No test order dependencies, no setup/teardown for shared mutable globals, no flakiness from hidden state. You can assert on exact values and be confident nothing else modified them.</p>
</li>
<li>
<p><strong>One-way data flow.</strong> Bloc is built on the idea that state flows in one direction: Bloc emits, UI reacts. Immutability enforces this. The UI cannot accidentally mutate state; it can only dispatch events. The Bloc is the only place that produces new states. That constraint makes the architecture simple to understand and prevents entire classes of bugs (e.g. a widget "fixing" state locally and breaking other parts of the app).</p>
</li>
<li>
<p><strong>Events should be immutable too.</strong> Events represent "what happened" at a point in time. If an event could be mutated after being dispatched, the Bloc might process a different payload than what was originally sent, or the same event object could be reused and modified across multiple dispatches, leading to unpredictable behavior. Immutable events ensure each dispatch is a well-defined, unchangeable record of user intent or system input. Here's a visual contrast.</p>
</li>
</ul>
<p><strong>Mutable</strong> — dangerous, anyone can change it:</p>
<pre><code>class BadState {
  List&lt;User&gt; users = [];  // mutable
}
// Some widget: state.users.add(newUser);  ← hidden mutation, hard to trace
</code></pre>
<p><strong>Immutable</strong> — create new state instead:</p>
<pre><code>class GoodState {
  final List&lt;User&gt; users;
  GoodState(this.users);
}
// New state: GoodState([...state.users, newUser])  ← explicit, traceable
</code></pre>
<p><strong>With Freezed <code>copyWith</code></strong> — ergonomic updates without mutating:</p>
<pre><code>state.copyWith(users: [...state.users, newUser]);
</code></pre>
<p>In short, immutability turns state and events into stable, predictable values that flow through your app in a clear, auditable way. It's not just a style choice—it's what makes Bloc's architecture reliable and maintainable at scale.</p>
<h3>Sealed classes and Pattern Matching</h3>
<p>Before Dart 3, modeling a finite set of states or events (e.g. <code>Loading | Success | Error</code>) required abstract classes with multiple implementations. The compiler couldn't know all possible subtypes, so you had to remember to handle every case manually—forgetting one often led to runtime errors or silent bugs. Dart 3 introduced <strong>sealed classes</strong> and <strong>pattern matching</strong>, which solve this at the language level.</p>
<ul>
<li>
<p><strong>What is a sealed class?</strong> A sealed class is a superclass whose direct subtypes are known and restricted by the compiler. You declare all possible variants in the same library (or with <code>sealed</code>), and no one can add new subtypes elsewhere. For Bloc, that means your state can be <code>Loading</code>, <code>Success</code>, or <code>Error</code>—and the compiler knows that's the complete list.</p>
</li>
<li>
<p><strong>How Freezed uses them.</strong> Freezed generates sealed unions for you. When you define <code>@freezed</code> states like <code>Loading</code>, <code>Success(data)</code>, and <code>Error(message)</code>, Freezed produces a sealed class hierarchy. Each variant is a distinct subtype, and together they form a closed, exhaustively known set.</p>
</li>
<li>
<p><strong>What is pattern matching?</strong> Pattern matching lets you branch on the <em>shape</em> of a value—its type and fields—in a single expression. In Dart, you use <code>switch</code> (or <code>switch</code> expressions) with pattern matching: the compiler checks that you've handled every possible case. If you add a new state variant later and forget to handle it, you get a compile error instead of a runtime crash.</p>
</li>
<li>
<p><strong>The real benefit.</strong> Sealed classes + pattern matching give you <strong>exhaustiveness checking</strong>. When you <code>switch</code> on state, the compiler ensures you handle <code>Loading</code>, <code>Success</code>, and <code>Error</code>. Add a new variant like <code>Refreshing</code>? The compiler tells you exactly where you need to update your code. That turns "did I handle every case?" from a manual, error-prone checklist into something the compiler enforces—making your Bloc states safer and easier to evolve.</p>
</li>
</ul>
<p><strong>Define states with Freezed:</strong></p>
<pre><code>@freezed
class UserState with _$UserState {
  const factory UserState.initial() = _Initial;
  const factory UserState.loading() = _Loading;
  const factory UserState.loaded(User user) = _Loaded;
  const factory UserState.error(String message) = _Error;
}
</code></pre>
<p><strong>Pattern match in the UI</strong> — the compiler enforces that all cases are handled:</p>
<pre><code>return switch (state) {
  UserState.initial() =&gt; const Text('Tap to load'),
  UserState.loading() =&gt; const CircularProgressIndicator(),
  UserState.loaded(:final user) =&gt; Text(user.name),
  UserState.error(:final message) =&gt; Text('Error: $message'),
};
</code></pre>
<p>Add a new variant like <code>UserState.refreshing()</code>? The compiler will error until you handle it everywhere. That's the power of exhaustiveness checking—no forgotten cases at runtime.</p>
<h2>Multi-state vs Mono-state</h2>
<p>There are two main ways to define Bloc state: <strong>multi-state</strong> (separate state classes for each variant, like union types) and <strong>mono-state</strong> (a single state class with variables inside—e.g. an enum for status plus nullable data and error fields). Both are valid, but they lead to different ergonomics in the Bloc and in the UI.</p>
<h3>Mono-state</h3>
<p>One class, multiple variables:</p>
<pre><code>class UserState {
  final UserStatus status;
  final User? user;
  final String? errorMessage;
  UserState({required this.status, this.user, this.errorMessage});
}
enum UserStatus { initial, loading, loaded, error }
</code></pre>
<ul>
<li><strong>The benefit</strong>: fewer classes, simple to add new statuses.</li>
<li><strong>The downside</strong>: invalid combinations are possible (e.g. <code>status == loaded</code> but <code>user == null</code>), and the UI has to reason about which fields are valid for each status. You end up with <code>if (state.status == UserStatus.loaded &amp;&amp; state.user != null)</code>—manual guards and a less expressive model of what the app state actually is.</li>
</ul>
<h3>Multi-state</h3>
<p>One variant per state, each with only the data it needs:</p>
<pre><code>@freezed
class UserState with _$UserState {
  const factory UserState.initial() = InitialUserState;
  const factory UserState.loading() = LoadingUserState;
  const factory UserState.loaded(User user) = LoadedUserState;
  const factory UserState.error(String message) = ErrorUserState;
}
</code></pre>
<ul>
<li><strong>The benefit</strong>: each state is self-describing. <code>UserState.loaded(user)</code> <em>always</em> has a user; <code>UserState.error(message)</code> <em>always</em> has a message. No null checks, no invalid combinations. The compiler and pattern matching enforce that you only access data when the state actually contains it.</li>
<li><strong>The downside</strong>: more classes, more boilerplate to add new statuses. And some ambiguity when defining read state and write state (will see that later).</li>
</ul>
<p>I prefer <strong>multi-state</strong> for a more elegant UI and a more expressive way to model app states. The UI maps directly to the states: each branch of the <code>switch</code> handles exactly one meaningful state, and the data is available by construction. The code reads like "when initial, show this; when loading, show that; when loaded, show the user." It makes the flow of your app explicit and keeps the UI free of defensive null checks and status flags. Mono-state can work for very simple flows, but as complexity grows, multi-state scales better and stays easier to reason about.</p>
<h3>BlocBuilder and BlocListener with multi-state</h3>
<p><strong>BlocBuilder</strong> rebuilds the widget when the state changes. Use it for the visual representation of state—what the user sees. With multi-state, you typically <code>switch</code> on the state and return a widget for each variant. No <code>buildWhen</code> needed if you want to react to every state; use <code>buildWhen</code> only when you want to skip rebuilds for certain transitions (e.g. don't rebuild when going from <code>loading</code> to <code>error</code> if both show the same scaffold).</p>
<pre><code>BlocBuilder&lt;UserBloc, UserState&gt;(
  builder: (context, state) =&gt; switch (state) {
    InitialUserState() =&gt; ElevatedButton(
        onPressed: () =&gt; context.read&lt;UserBloc&gt;().add(UserLoadRequested()),
        child: const Text('Load user'),
      ),
    LoadingUserState() =&gt; const Center(child: CircularProgressIndicator()),
    LoadedUserState(:final user) =&gt; UserProfile(user: user),
    ErrorUserState(:final message) =&gt; Text('Error: $message'),
  },
)
</code></pre>
<p><strong>BlocListener</strong> runs side effects (snackbars, dialogs, navigation) when the state changes. It does <em>not</em> build widgets—it listens and reacts. Use it for one-time or ephemeral UI feedback that shouldn't be part of the widget tree (e.g. show a snackbar on error, navigate away on success). Prefer <code>listenWhen</code> to avoid running the same effect multiple times for the same logical event.</p>
<pre><code>BlocListener&lt;UserBloc, UserState&gt;(
  listenWhen: (previous, current) =&gt; current case UserState.error(),
  listener: (context, state) =&gt; switch (state) {
    ErrorUserState(:final message) =&gt; ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(message)),
    ),
    _ =&gt; null,
  },
  child: BlocBuilder&lt;UserBloc, UserState&gt;(...),
)
</code></pre>
<p><strong>BlocConsumer</strong> combines both when you need listener and builder in the same place—side effects in <code>listener</code>, UI in <code>builder</code>. Use <code>listenWhen</code> and <code>buildWhen</code> to control when each runs.</p>
<pre><code>BlocConsumer&lt;UserBloc, UserState&gt;(
  listenWhen: (prev, curr) =&gt; curr case UserState.error(),
  listener: (context, state) =&gt; switch (state) {
    ErrorUserState(:final message) =&gt; ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(message)),
    ),
    _ =&gt; null,
  },
  builder: (context, state) =&gt; switch (state) {
    InitialUserState() =&gt; const Placeholder(),
    LoadingUserState() =&gt; const CircularProgressIndicator(),
    LoadedUserState(:final user) =&gt; UserProfile(user: user),
    ErrorUserState(:final message) =&gt; Text('Error: $message'),
  },
)
</code></pre>
<p><strong>Summary:</strong> <code>BlocBuilder</code> = rebuild UI. <code>BlocListener</code> = side effects (snackbars, navigation). <code>BlocConsumer</code> = both. With multi-state, pattern matching keeps each branch clean and the compiler ensures you handle every case.</p>
<h2>CRUD structure: separating reads and writes</h2>
<p>A clean way to structure CRUD is to split <strong>reads</strong> (the list) from <strong>writes</strong> (create, update, delete). Use a <code>[Feature]ListCubit</code> to stream or load the list, and a <code>[Feature]Bloc</code> for mutations. The UI uses <code>BlocListener</code> on the mutation Bloc to trigger side effects (e.g. refresh the list, show snackbars)—no need to couple the list logic to mutations.</p>
<h3>States and events</h3>
<p><strong>ItemsListCubit</strong> — read-only, holds the list:</p>
<pre><code>@freezed
class ItemsListState with _$ItemsListState {
  const factory ItemsListState.initial() = InitialItemsListState;
  const factory ItemsListState.loading() = LoadingItemsListState;
  const factory ItemsListState.loaded(List&lt;Item&gt; items) = LoadedItemsListState;
  const factory ItemsListState.error(String message) = ErrorItemsListState;
}

class ItemsListCubit extends Cubit&lt;ItemsListState&gt; {
  final ItemsRepository _repo;

  ItemsListCubit(this._repo) : super(const ItemsListState.initial());

  Future&lt;void&gt; load() async {
    emit(const ItemsListState.loading());
    try {
      final items = await _repo.getItems();
      emit(ItemsListState.loaded(items));
    } catch (e) {
      emit(ItemsListState.error(e.toString()));
    }
  }

  void refresh() =&gt; load();
}
</code></pre>
<p><strong>ItemsBloc</strong> — mutations only:</p>
<pre><code>@freezed
class ItemMutationEvent with _$ItemMutationEvent {
  const factory ItemMutationEvent.create(Item item) = CreateItemMutationEvent;
  const factory ItemMutationEvent.update(Item item) = UpdateItemMutationEvent;
  const factory ItemMutationEvent.delete(String id) = DeleteItemMutationEvent;
}

@freezed
class ItemMutationState with _$ItemMutationState {
  const factory ItemMutationState.initial() = InitialItemMutationState;
  const factory ItemMutationState.creating() = CreatingItemMutationState;
  const factory ItemMutationState.createSuccess(Item item) = _CreateSuccess;
  const factory ItemMutationState.createError(String message) = CreateErrorItemMutationState;
  const factory ItemMutationState.updating() = UpdatingItemMutationState;
  const factory ItemMutationState.updateSuccess(Item item) = UpdateSuccessItemMutationState;
  const factory ItemMutationState.updateError(String message) = UpdateErrorItemMutationState;
  const factory ItemMutationState.deleting() = DeletingItemMutationState;
  const factory ItemMutationState.deleteSuccess(String id) = DeleteSuccessItemMutationState;
  const factory ItemMutationState.deleteError(String message) = DeleteErrorItemMutationState;
}

class ItemsBloc extends Bloc&lt;ItemMutationEvent, ItemMutationState&gt; {
  final ItemsRepository _repo;

  ItemsBloc(this._repo) : super(const ItemMutationState.idle()) {
    on&lt;_Create&gt;(_onCreate);
    on&lt;_Update&gt;(_onUpdate);
    on&lt;_Delete&gt;(_onDelete);
  }

  Future&lt;void&gt; _onCreate(_Create e, Emitter&lt;ItemMutationState&gt; emit) async {
    emit(const ItemMutationState.creating());
    try {
      final item = await _repo.create(e.item);
      emit(ItemMutationState.createSuccess(item));
    } catch (e) {
      emit(ItemMutationState.createError(e.toString()));
    }
  }
  // _onUpdate, _onDelete similar...
}
</code></pre>
<h3>UI: BlocListener triggers list refresh</h3>
<p>When a mutation succeeds, the UI uses <code>BlocListener</code> to refresh the list—no coupling between <code>ItemsBloc</code> and <code>ItemsListCubit</code>. Side effects stay in the UI layer.</p>
<pre><code>BlocListener&lt;ItemsBloc, ItemMutationState&gt;(
  listenWhen: (prev, curr) =&gt;
      curr case ItemMutationState.createSuccess() ||
      curr case ItemMutationState.updateSuccess() ||
      curr case ItemMutationState.deleteSuccess(),
  listener: (context, state) {
    context.read&lt;ItemsListCubit&gt;().refresh();
    ScaffoldMessenger.of(context).showSnackBar(switch (state) {
      CreateSuccessItemMutationState() =&gt; const SnackBar(content: Text('Created')),
      UpdateSuccessItemMutationState() =&gt; const SnackBar(content: Text('Updated')),
      DeleteSuccessItemMutationState() =&gt; const SnackBar(content: Text('Deleted')),
      _ =&gt; null,
    });
  },
  child: BlocBuilder&lt;ItemsListCubit, ItemsListState&gt;(
    builder: (context, state) =&gt; switch (state) {
      InitialItemsListState() =&gt; const SizedBox(),
      LoadingItemsListState() =&gt; const Center(child: CircularProgressIndicator()),
      LoadedItemsListState(:final items) =&gt; ListView.builder(...),
      ErrorItemsListState(:final message) =&gt; Text(message),
    },
  ),
)
</code></pre>
<h3>CQRS-style: stream the list instead of fetching</h3>
<p>You can go further with a CQRS-style read model: the list subscribes to a <strong>stream</strong> from the repository. When the backend or local store changes (e.g. after create/update/delete), the stream emits and the Cubit emits a new state. No manual <code>refresh()</code>—the list stays in sync automatically.</p>
<pre><code>class ItemsListCubit extends Cubit&lt;ItemsListState&gt; {
  final ItemsRepository _repo;
  StreamSubscription&lt;List&lt;Item&gt;&gt;? _subscription;

  ItemsListCubit(this._repo) : super(const ItemsListState.initial());

  void watch() {
    emit(const ItemsListState.loading());
    _subscription?.cancel();
    _subscription = _repo.watchItems().listen(
      (items) =&gt; emit(ItemsListState.loaded(items)),
      onError: (e) =&gt; emit(ItemsListState.error(e.toString())),
    );
  }

  @override
  Future&lt;void&gt; close() {
    _subscription?.cancel();
    return super.close();
  }
}
</code></pre>
<p>With <code>watch()</code>, you call it once (e.g. when entering the screen). The repository's <code>watchItems()</code> stream (e.g. Firestore, Room, or a local reactive store) pushes updates whenever data changes. Mutations in <code>ItemsBloc</code> write to the same store; the stream emits, and the list updates. No <code>BlocListener</code> needed for refresh—though you may still use it for snackbars or navigation. The read model (list) and write model (mutations) are decoupled; the stream is the bridge.</p>
<hr />
<p>Bloc is powerful when you lean into it: immutable, multi-state definitions with Freezed and Equatable, sealed classes and pattern matching for exhaustiveness, and a clear split between reads and writes. Use Bloc for traceable mutations, Cubit for simple reads. Let <code>BlocListener</code> handle side effects in the UI, and consider a CQRS-style stream for lists when your data source supports it. This is the approach I've found scales best—state stays predictable, the UI stays clean, and the compiler helps catch mistakes before they reach production. I hope it works for you too.</p>
]]></content>
        <author>
            <name>fres</name>
            <uri>https://fres.space</uri>
        </author>
        <published>2026-02-01T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Design Patterns in Java]]></title>
        <id>https://fres.space/posts/design-patterns-en/</id>
        <link href="https://fres.space/posts/design-patterns-en/"/>
        <updated>2025-03-12T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[A comprehensive guide to understanding and implementing design patterns in Java, including creational, structural, and behavioral patterns.]]></summary>
        <content type="html"><![CDATA[<p><img src="https://5yyithvls1.ufs.sh/f/3nsI94TDxXoGu5NiATPw2RKvPU9nGi3dOrj1ZQ5msSeHtNkl" alt="" /></p>
<h1>Creational Design Patterns</h1>
<p>The creational design patterns are useful when you have to "create" something (lol).</p>
<p>They includes the following patterns:</p>
<ul>
<li>Factory Method</li>
<li>Abstract Factory</li>
<li>Builder</li>
<li>Prototype</li>
<li>Singleton</li>
</ul>
<p>Nothing to say more about Creational Patterns in general since it's just "sugar syntax" to group design patterns into parent-classes of designs.</p>
<h2>Factory Method</h2>
<p>The Factory Method is a Creational Design Pattern that comes in handy when the application requires the creation of the same object multiple times.</p>
<p>To avoid ripeat the logic of the creation of this particular object the Factory Method allows the developer to don't repeat himself.</p>
<p>In a one-line sentence the Factory Method allows the developer to hide the business logic of the creation of an object in the application</p>
<p>Based on that definition we could think that the Factory Method behaves in this kind of way:</p>
<ul>
<li>You have some sort of logic behind the creation of an Object</li>
<li>You do want to avoid repetition</li>
<li>You create a Factory Method to handle this</li>
</ul>
<p>Let's see it with a quick example.</p>
<pre><code>class Prodcut {
 private int id;
 private int price;

  public Product(int id, int price) {
    this.id = id;
    this.price = price;
  }

}

class FactoryProduct {
  private static int currentId = 0;

  public static Product createProduct(int price) {
    currentId++;
    return new Product(currentId, price);
  }
}
</code></pre>
<p>This example is actually pretty stupid and probably also wrong in terms of logic.</p>
<p>The Factory Method capabilities do not stops here.</p>
<p>The Factory Method can be used to create objects of different classes that share the same parent class, or mor generally, the real benefits of the Factory Method are shown wiht polymorphism.</p>
<p>Let's see a more complex example.</p>
<p>Let's say you have a game in which you have to create space ships. The more the level of the game increases the more the space ships are powerful.</p>
<p>You could have a parent class <code>SpaceShip</code> and then you could have different classes that extends the <code>SpaceShip</code> class.</p>
<p>The Factory Method can be used to create the different space ships based on the level of the game.</p>
<pre><code>abstract class SpaceShip {
  private int health;
  private int damage;

  public SpaceShip(int health, int damage) {
    this.health = health;
    this.damage = damage;
  }

  public void attack() {
    System.out.println("Attacking with " + damage + " damage");
  }
}

class WeakSpaceShip extends SpaceShip {
  public WeakSpaceShip() {
    super(100, 10);
  }
}

class MediumSpaceShip extends SpaceShip {
  public MediumSpaceShip() {
    super(200, 20);
  }
}

class StrongSpaceShip extends SpaceShip {
  public StrongSpaceShip() {
    super(300, 30);
  }
}

class SpaceShipFactory {
  public static SpaceShip createSpaceShip(int level) {
    switch(level) {
      case 1:
        return new WeakSpaceShip();
      case 2:
        return new LevMediumSpaceShipel2SpaceShip();
      case 3:
        return new StrongSpaceShip();
      default:
        return null;
    }
  }
}
</code></pre>
<p>In this example whenver we need to create a new space ship we can use the <code>SpaceShipFactory</code> class to create the space ship based on the level of the game.</p>
<p>But let's say taht we also have to create Aliens in the game, also the Aliens increase their power based on the level of the game, but of course the aliens are not space ships, and they have different powers.</p>
<p>In that case the correct way to proceed is to create Factory based on the level of the game.</p>
<pre><code>class Alien {
  private int lifePoints;
  private int criticalDamage;

  public Entity(int lifePoints, int criticalDamage) {
    this.lifePoints = lifePoints;
    this.criticalDamage = criticalDamage;
  }

  public void attack() {
    System.out.println("Attacking with " + criticalDamage + " critical damage");
  }
}

class WeakAlien extends Alien {
  public WeakAlien() {
    super(100, 10);
  }
}

class MediumAlien extends Alien {
  public MediumAlien() {
    super(200, 20);
  }
}

class StrongAlien extends Alien {
  public StrongAlien() {
    super(300, 30);
  }
}
</code></pre>
<h2>Abstract Factory Method</h2>
<p>We just decide, as shown before, that the game has different levels, and also has different entities that has some sort of power based on the level of the game.</p>
<p>In that case we could just create a new Factory for aliens and so having something like this:</p>
<pre><code>class AlienFactory {
  public static Alien createAlien(int level) {
    switch(level) {
      case 1:
        return new WeakAlien();
      case 2:
        return new MediumAlien();
      case 3:
        return new StrongAlien();
      default:
        return null;
    }
  }
}
</code></pre>
<blockquote>
<p>[!WARNING]
This snippet of code is actually bad, because we are repeating the same logic of the <code>SpaceShipFactory</code> class.</p>
</blockquote>
<p>Plus if we want to add a new level to the game we then have to edito both the <code>SpaceShipFactory</code> and the <code>AlienFactory</code> classes.</p>
<p>In that case so we have to shift our focus on problem and start thinking about the family of problem.</p>
<p>So the problem is that we have to create different entities based on the level of the game -&gt; So we need a <code>LevelFactory</code>.</p>
<p>This <code>LevelFactory</code> will be <code>abstract</code> since it doesn't have any kind of <strong>concrete implementation</strong> but it just defines the methods that the concrete factories have to implement.</p>
<p>In that case our <strong>concrete Factories</strong> will be the <code>Level1Factory</code>, <code>Level2Factory</code> and <code>Level3Factory</code>.</p>
<p>Let's see the code:</p>
<pre><code>abstract class LevelFactory {
  abstract SpaceShip createSpaceShip();
  abstract Alien createAlien();
}

class Level1Factory extends LevelFactory {
  @override
  SpaceShip createSpaceShip() {
    return new WeakSpaceShip();
  }

  @override
  Alien createAlien() {
    return new WeakAlien();
  }
}

class Level2Factory extends LevelFactory {
  @override
  SpaceShip createSpaceShip() {
    return new MediumSpaceShip();
  }

  @override
  Alien createAlien() {
    return new MediumAlien();
  }
}

class Level3Factory extends LevelFactory {
  @override
  SpaceShip createSpaceShip() {
    return new StrongSpaceShip();
  }

  @override
  Alien createAlien() {
    return new StrongAlien();
  }
}
</code></pre>
<p>By doing that we actually create a solution for a set of problem (having more levels and more entities that depends on the level of the game), and we can easly add new levels to the game without headache and without going to change any client code that uses our <strong>Factories</strong> because in that case the benefit is that our <em>client</em> doesn't have to depend on the concrete classes but just on the abstract classes.</p>
<p>In that example the benefit is clear:</p>
<pre><code>
abstract class Level {
  private LevelFactory levelFactory;
  private String levelName;

  public Level(LevelFactory levelFactory, String levelName) {
    this.levelFactory = levelFactory;
    this.levelName = levelName;
  }
}

class Level1 extends Level {
  public Level1(LevelFactory levelFactory, String levelName) {
    super(levelFactory, levelName);
  }
}
</code></pre>
<p>An actual implementation of this would be:</p>
<pre><code>public class Main {
  public static void main(String[] args) {
    // assuming that the client choose the level 1
    Level1 level = new Level1(new Level1Factory(), "Level 1");
    SpaceShip spaceShip = level.createSpaceShip();
    Alien alien = level.createAlien();

    spaceShip.attack();
    alien.attack();
  }
}
</code></pre>
<h2>Builder</h2>
<p>The Builder is a Creation Design Patterns very very useful and famous. It's mainly used when you have to <em>build</em> an Object and its creation process may involves several steps (and not every step is required) that you want the client to abstract from.</p>
<p>A quick and most famous axample would be an <code>http</code> call in wich you have to "assemble" several pieces togheter (url, headers, body, etc...) in order to create a valid <code>http</code> request, but the deal is that not every <code>http</code> request needs to have a body, or headers, or a specific method, etc...</p>
<p>A quick example to get you in the mood:</p>
<pre><code>public static void main(String[] args) {
  HttpRequest request = new HttpRequest.Builder()
    .setUrl("https://api.example.com")
    .setMethod("GET")
    .setHeaders(new HashMap&lt;String, String&gt;() {{
      put("Authorization", "Bearer 123456");
    }})
    .build();
}
</code></pre>
<blockquote>
<p>[!NOTE]
This is a quick example and it's not a real code that you can run, but it's just to give you an idea of how the Builder Pattern works.</p>
</blockquote>
<p>Just for fun let's stick with the <code>SpaceShip</code> example. In the previous example we saw that a <code>SpaceShip</code> can have a <code>health</code> and a <code>damage</code> property. But now let's dive more into the concept of the <code>SpaceShip</code> itself, so more a place in which the atronauts can navigate into the sky and more.</p>
<p>So let's say we materially want to build the Space Ship, a spaceship needs several parts to be built, and not every part is required to build a spaceship.</p>
<p>In that case we can use the Builder Pattern to build the spaceship.</p>
<pre><code>class SpaceShip {
  private String name;
  private String model;
  private int crew;
  private int maxSpeed;
  private Srting fuel;
  private int health;

  public SpaceShip(String name, String model, int crew, int maxSpeed, String fuel, int health) {
    this.name = name;
    this.model = model;
    this.crew = crew;
    this.maxSpeed = maxSpeed;
    this.fuel = fuel;
    this.health = health;
  }
}

public interface Builder {
  void setName(String name);
  void setModel(String model);
  void setCrew(int crew);
  void setMaxSpeed(int maxSpeed);
  void setFuel(String fuel);
  void setHealth(int health);
}

class SpaceShipBuilder implements Builder {
  private String name;
  private String model;
  private int crew;
  private int maxSpeed;
  private String fuel;
  private int health;

  @override
  public void setName(String name) {
    this.name = name;
  }

  @override
  public void setModel(String model) {
    this.model = model;
  }

  @override
  public void setCrew(int crew) {
    this.crew = crew;
  }

  @override
  public void setMaxSpeed(int maxSpeed) {
    this.maxSpeed = maxSpeed;
  }

  @override
  public void setFuel(String fuel) {
    this.fuel = fuel;
  }

  @override
  public void setHealth(int health) {
    this.health = health;
  }

  public SpaceShip build() {
    return new SpaceShip(this.name, this.model, this.crew, this.maxSpeed, this.fuel, this.health);
  }
}
</code></pre>
<p>Of course in this case we are using primitives data types, but you can also build up more complex examples.</p>
<p>So couple of things to sum up:</p>
<ul>
<li>The <code>SpaceShip</code> class is the class that we want to build.</li>
<li>The <code>Builder</code> interface - so the contract - that the <code>SpaceShipBuilder</code> class has to implement.</li>
<li>An important method to keep in mind is the <code>buid()</code> method, that is the method that actually builds the <code>SpaceShip</code> object, basically what happens is that every time you <code>set</code> something, then the reference of the attribute of the class is updated and after all the sets, when you are done, you can call the <code>build()</code> method that will return the <code>SpaceShip</code> object with all the attributes setted.</li>
<li>So if you are wondering how the builder remember everything...then the answer is that all the attributes are stored in-memory in the <code>SpaceShipBuilder</code> class.</li>
</ul>
<p>A quick example of how to use the Builder Pattern:</p>
<pre><code>public static void main(String[] args) {
  SpaceShip spaceShip = new SpaceShipBuilder()
        .setName("SpaceX")
        .setModel("Falcon 9")
        .setCrew(4)
        .setMaxSpeed(1000)
        .setFuel("Kerosene")
        .setHealth(100)
        .build();
}
</code></pre>
<p>In conclusion the Builder Pattern is very useful to decouple (and abstract) the client from the object creation process, and most imporant to separate logic for certain objects that requires a lot of steps to be created.</p>
<blockquote>
<p>[!TIP]
The Buidler Pattern is very used in Frameworks and Libraries, that most of the times abstract as much as possible for the developer to use the library.</p>
</blockquote>
<h2>Prototype</h2>
<p>The Prototype Pattern is a Creational Design Pattern that is used when you have to create a new object by copying an existing object without making your code dependent on their classes.</p>
<p>This pattern is per se very easy to understand and to apply, and it's also very handy for some scenarios in which you have to duplicate an object. When performing some business logic, the duplication of an objects is usually very common and so the Prototype Pattern solves the biolerplate code that you have to write to duplicate an object like <code>new</code> and the fact that you have to pass all the attributes of the object to the new object.</p>
<p>So let's say that you have a <code>SpaceShip</code> object and you want to duplicate it, you can use the Prototype Pattern to do that.</p>
<pre><code>class SpaceShip {
  private String name;
  private String model;
  private int crew;
  private int maxSpeed;
  private String fuel;
  private int health;

  public SpaceShip(String name, String model, int crew, int maxSpeed, String fuel, int health) {
    this.name = name;
    this.model = model;
    this.crew = crew;
    this.maxSpeed = maxSpeed;
    this.fuel = fuel;
    this.health = health;
  }

  public SpaceShip clone() {
    return new SpaceShip(this);
  }
}
</code></pre>
<p>This will also work for the class that inherits from the <code>SpaceShip</code> class.</p>
<pre><code>class WeakSpaceShip extends SpaceShip {
  public WeakSpaceShip(String name, String model, int crew, int maxSpeed, String fuel, int health) {
    super(name, model, crew, maxSpeed, fuel, health);
  }

  public WeakSpaceShip(WeakSpaceShip weakSpaceShip) {
    super(weakSpaceShip);
  }

  @override
  public SpaceShip clone() {
    return new WeakSpaceShip(this);
  }
}
</code></pre>
<p>So double ++ for that :D.</p>
<p>To conclude the Prototype Pattern do not need any kind of interface or abstract class, but it's just a method that you can add to your class to duplicate the object.</p>
<p>Eventualy you can also create an <code>Clonable</code> or <code>Prototype</code> interface that has the <code>clone()</code> method and then you can implement that interface in the class that you want to duplicate, but it's not that big of a deal!</p>
<h2>Singleton</h2>
<p>The Singleton Pattern is one of the most abused pattern in the world of programming, and it's also one of the most famous.</p>
<p>It's very useful when you have to create an object that has to be unique across all the life-cycle of the application, so you have to create only one instance of that object.</p>
<p>Its implementation is very straightforward and make the job done without too much effort.</p>
<pre><code>class Singleton {
  private static Singleton instance;

  private Singleton() {}

  public static Singleton getInstance() {
    if (instance == null) {
      instance = new Singleton();
    }

    return instance;
  }
}
</code></pre>
<p>The Singleton Pattern is also very useful when you have to create a shared resource across the application, like a <code>Logger</code> or a <code>Database Connection</code>.</p>
<p>I don't think I need to make some sort of exmaple related to our <strong>SpaceShip Game</strong> because it's pretty clear how the music goes.</p>
<h1>Structural Design Patterns</h1>
<p>The Structural Design Patterns are used to create a structure of objects in a way that they can work together in a more efficient way.</p>
<h2>Adapter</h2>
<p>The Adapter Pattern is a Structural Design Pattern that allows objects with incompatible interfaces to work together.</p>
<p>Basically when you want to provide some sort of communication bwtween two objects that have different interfaces you can use the Adapter Pattern.</p>
<p>For example</p>
<ul>
<li>if you have an API that communicates via <code>XML</code> but you application communicates via <code>JSON</code> you can use the Adapter Pattern to make the two objects communicate.</li>
<li>or if you have some legacy code in your application that you want to use but it's not compatible with the new code you can use the Adapter Pattern to make the two objects communicate.</li>
</ul>
<p>These are just a couple of examples of how the Adapter Pattern can be used.</p>
<p>Sticking with the <strong>SpaceShip Game</strong> example, let's pretend that we have a <code>SpaceShip</code> class that has a <code>health</code> and a <code>damage</code> property, but we want to use the <code>SpaceShip</code> class in a game that has a <code>lifePoints</code> and a <code>criticalDamage</code> property.</p>
<p>In that case we can use the Adapter Pattern to make the two objects communicate.</p>
<pre><code>class SpaceShip {
  private int health;
  private int damage;

  public SpaceShip(int health, int damage) {
    this.health = health;
    this.damage = damage;
  }

  public fire() {
    System.out.println("Firing with " + damage + " damage");
  }
}

class Alien {
  private int lifePoints;
  private int criticalDamage;

  public Alien(int lifePoints, int criticalDamage) {
    this.lifePoints = lifePoints;
    this.criticalDamage = criticalDamage;
  }
}

class AlienAdapter extends SpaceShip {
  private Alien alien;

  public AlienAdapter(Alien alien) {
    super(alien.getLifePoints(), alien.getCriticalDamage());
    this.alien = alien;
  }
}
</code></pre>
<p>In this example the <code>AlienAdapter</code> class is the Adapter that allows the <code>SpaceShip</code> and the <code>Alien</code> class to communicate.</p>
<p>A quick example of how to use the Adapter Pattern:</p>
<pre><code>public static void main(String[] args) {
  Alien alien = new Alien(100, 10);
  AlienAdapter alienAdapter = new AlienAdapter(alien);
  // we can use the AlienAdapter as a SpaceShip
  alienAdapter.fire();
}
</code></pre>
<blockquote>
<p>[!NOTE]
The Adapter Pattern doesn't need any kind of interface or abstract class since it's itself a child of a parent class, so it basically a smart way to use polymorphism and inheritance.</p>
</blockquote>
<h2>Bridge</h2>
<p>The Bridge Pattern is more an abstract concept than a real implementation. It's used when you have to decouple an abstraction from its implementation so that the two can vary independently.</p>
<p>For example when you have a monolith application and you want to split it into microservices, you can use the Bridge Pattern to decouple the abstraction from the implementation.
By doing that if you have a problem, or you have to make an improvement to the <em>AuthService</em> you can do that without affecting the other services.</p>
<p>Or another more practical example is a <strong>Cross Platform</strong> framework that can compile on several platforms, in that case the Framework serves as an abstraction layer that avoids the developer to repeat the same functionality for each platform.</p>
<p>Say that, explaining what actually is a Bridge can be a bit tricky, but the concept is very simple.</p>
<p>To make it even more clear I would like to make a distinction between the Bridge Pattern and the Adapter Pattern.</p>
<p>The Adapter Pattern that we saw earlier is commonly used with an existing app or system in order to make some otherwise-incompatible classes work together, on the other hand the Bridge Pattern is used up front in the design of a system to let the developers works indipendently havving a bridge between the two.</p>
<h2>Composite</h2>
<p>The Composite Pattern is a Structural Design Pattern that allows you to compose objects into tree structures to represent part-whole hierarchies.</p>
<p>So automatically this pattern is very used when in your application there's a well structured hierarchy of objects that you want to represent.</p>
<p>At first sight you may do not think about any real example of this pattern, it was the same for me before reading this example.</p>
<p>In some UI Framwork the UI components are rapresented in a tree-structure. Usually in these structure only the leaf nodes of the tree are responsible to the actually "paint on the canvas" (yes some UI Framworks actually paints pixels on a blank canvas, like Flutter for mobile development). In those scenarios as u might imagine the structure is something like this:</p>
<pre><code>├── CustomButton
│   ├── Button
│       ├── Container
│           ├── Widget
│               ├── Element
│                   ├── RenderObject
│                       ├── RenderBox
</code></pre>
<p>This is just a made up example but the concept seems clear, the CustomButton is the root of the hierarchy and is the one that the user has defined on top of the Framework one ("Button"), and the Button is the one that the Framework has defined on top of the Container, and so on.</p>
<p>The RenderBox is the leaf node of the tree and is the one that actually paints on the canvas (or more professional way -&gt; it render the object).</p>
<p>The point here is the fact that in a <em>class</em> POV the CustomButton, Container, Widget and so on don't have any <code>render()</code> or <code>paint()</code> method, but they have a <code>child</code> property that is the reference to the next object in the hierarchy.</p>
<p>Of course a node can also have more than one child, but the point here is that only the leaf are the concrete <em>painters</em> of the thing in the UI.</p>
<p>The same concept you can apply to the <code>Dot</code> concept. A <code>Dot</code> can be a <code>Line</code> that can be a <code>Square</code> and so on.</p>
<h2>Decorator</h2>
<p>The Decorator Pattern is a Structural Design Pattern that allows you to add new functionality to an existing object without altering its structure.</p>
<p>So you can consider it as a wrapper around an object that doesn't currently do what you need to do, so you use a Decorator, to <em>decorate</em> the object and make it do what you need to do.</p>
<p>Usually when you need to extend the functionality of an object in the <strong>OO</strong> world you would use inheritance, it works great, but it has its caveats.</p>
<p>Sometimes happen that you have class <code>A</code> that is being extended in class <code>B</code> since you need more funcionality. The first limitation here is that class <code>A</code> doesn't do what class <code>B</code> does, so if you ever needs a class that does what class <code>A</code> and <code>B</code> does then you <strong>CAN'T</strong> create a class <code>C</code> that extends both <code>A</code> and <code>B</code>, that's the limitation of the inheritance (technically in Python you can do that, but it has it's own caveats too).</p>
<p>So we understood that inheritance doesn't solves all our problems, sometime you need to use <strong>composition</strong>.</p>
<p>The Decorator Pattern is a way to use composition to extend the functionality of an object.</p>
<p>Let's see an example with the <code>SpaceShip</code> game, let's imagine that in our game we have different space ships that can have different weapons, and we want to add a weapon to a space ship.</p>
<p>Normally you would do something like this:</p>
<pre><code>class SpaceShip {
  private Weapon weapon;

  public SpaceShip(Weapon weapon) {
    this.weapon = weapon;
  }

  public void fire() {
    weapon.fire();
  }
}

abstract class Weapon {
  public abstract void fire() {}
}

class LaserWeapon extends Weapon {
  @override
  public void fire() {
    System.out.println("Firing with laser");
  }
}

class RocketWeapon extends Weapon {
  @override
  public void fire() {
    System.out.println("Firing with rocket");
  }
}

class PlasmaWeapon extends Weapon {
  @override
  public void fire() {
    System.out.println("Firing with plasma");
  }
}
</code></pre>
<p>So far so good, if we want to add a special weapon to a space ship we can do it like that:</p>
<pre><code>public static void main(String[] args) {
  SpaceShip spaceShip = new SpaceShip(new LaserWeapon());
  spaceShip.fire();
}
</code></pre>
<p>But what if we want to add more than one weapon to a space ship? We can't do that with the current implementation.</p>
<p>So we can use the Decorator Pattern to solve this problem.</p>
<pre><code>class SpaceShip {
  private Weapon weapon;

  public SpaceShip(Weapon weapon) {
    this.weapon = weapon;
  }

  public void fire() {
    weapon.fire();
  }

  public void setWeapon(Weapon weapon) {
    this.weapon = weapon;
  }
}

// the rest of the weapons classes...

abstract class SpaceShipDecorator extends SpaceShip {
  protected SpaceShip wrappedSpaceShip;

  public SpaceShipDecorator(SpaceShip wrappedSpaceShip, Weapon weapon) {
    this.wrappedSpaceShip = wrappedSpaceShip;
    this.wrappedSpaceShip.setWeapon(weapon);
  }

  public void fire() {
    wrappedSpaceShip.fire();
  }
}
</code></pre>
<p>Okay but, how can we actually use it?</p>
<pre><code>public static void main(String[] args) {
  SpaceShip spaceShip = new SpaceShip(new LaserWeapon());
  // will fire laser
  spaceShip.fire();

  SpaceShip spaceShipWithRocket = new RocketWeaponDecorator(spaceShip, new RocketWeapon());
  // will fire rocket
  spaceShipWithRocket.fire();

  SpaceShip spaceShipWithPlasma = new PlasmaWeaponDecorator(spaceShipWithRocket, new PlasmaWeapon());
  // will fire plasma
  spaceShipWithPlasma.fire();
}
</code></pre>
<p>And that's it, very handy, very easy.</p>
<h2>Facade</h2>
<p>The Facade Pattern is a pattern that handle the complex logic behind the scenes and provide a simple interface to the client.</p>
<p>Those <em>complex logic</em> ofter comes from a libarary or a framework, and the <strong>Facade</strong> provides a simple and intuitive interface to handle it.</p>
<p>Let's say that in our game we have someway to start the engine of the <code>StarShip</code> and we have to do several things to start the engine, like check the fuel, check the battery, check the oxygen, etc...</p>
<p>In that case we can use the Facade Pattern to provide a simple interface to start the engine.</p>
<pre><code>class SpaceShip {
  private Engine engine;

  public SpaceShip(Engine engine) {
    this.engine = engine;
  }
}

class Engine {
  public void checkFuel() {
    System.out.println("Checking fuel");
  }

  public void checkBattery() {
    System.out.println("Checking battery");
  }

  public void checkOxygen() {
    System.out.println("Checking oxygen");
  }

  public void start() {
    System.out.println("Starting engine");
  }
}

class EngineStarter {
  private Engine engine;

  public EngineStarter(Engine engine) {
    this.engine = engine;
  }

  public void startEngine() {
    engine.checkFuel();
    engine.checkBattery();
    engine.checkOxygen();
    engine.start();
  }
}
</code></pre>
<p>Okay let's pretend for a minute that the engine is a bit more complex than this...But the point here is that the <code>EngineStarter</code> so our <strong>Facade</strong> is providing good <strong>API</strong> to start the engine.</p>
<p>Let's see it in action:</p>
<pre><code>public static void main(String[] args) {
  SpaceShip spaceShip = new SpaceShip(new Engine());
  EngineStarter engineStarter = new EngineStarter(spaceShip.engine);
  engineStarter.startEngine();
}
</code></pre>
<h2>Flyweight</h2>
<p>The Flyweight Pattern is a Structural Design Pattern that allows you to share objects to reduce memory usage.</p>
<p>It basically enable use to avoid specifing some attributes of an object in multiple objects, but to share them in a common place.</p>
<p>Let's say for the SpaceShip game we have thousands of bullets being fired. Each bullet has a position, direction, speed, and appearance. The appearance (texture, color, shape) can be shared among many bullets to save memory.</p>
<pre><code>// Flyweight - shared bullet properties
class BulletType {
  private final String texture;
  private final String color;
  private final String shape;

  public BulletType(String texture, String color, String shape) {
    this.texture = texture;
    this.color = color;
    this.shape = shape;
  }
}

// Concrete bullet with unique state
class Bullet {
  private int x, y;  // position
  private int speed;
  private BulletType type; // shared flyweight

  public Bullet(int x, int y, int speed, BulletType type) {
    this.x = x;
    this.y = y;
    this.speed = speed;
    this.type = type;
  }
}

// Factory to manage shared BulletTypes
class BulletFactory {
  private Map&lt;String, BulletType&gt; bulletTypes = new HashMap&lt;&gt;();

  public BulletType getBulletType(String texture, String color, String shape) {
    String key = texture + color + shape;
    if (!bulletTypes.containsKey(key)) {
      bulletTypes.put(key, new BulletType(texture, color, shape));
    }
    return bulletTypes.get(key);
  }
}
</code></pre>
<p>The reason behind the Factory is that we want to avoid creating the same <code>BulletType</code> object multiple times, and the factory here comes in handy since we separate this logic from the client.
If you are wondering why we are using a <code>Map</code> to store the <code>BulletType</code> objects, the answer is that we want to avoid creating the same <code>BulletType</code> object multiple times.</p>
<p>Usage example:</p>
<pre><code>BulletFactory factory = new BulletFactory();
BulletType laserType = factory.getBulletType("laser", "red", "line");

// Create many bullets sharing the same BulletType
List&lt;Bullet&gt; bullets = new ArrayList&lt;&gt;();
for (int i = 0; i &lt; 1000; i++) {
  bullets.add(new Bullet(i, i, 10, laserType));
}
</code></pre>
<h2>Proxy</h2>
<p>The Proxy Pattern enable to control the access to a specific object.</p>
<p>Okay but how? It provides a placeholder for this object that the developer want to protect, in order to delegat it to the proxy object.</p>
<p>The Proxy Pattern is used when you want to add some sort of logic before or after the access to an object.</p>
<p>For example you can use the Proxy Pattern to add some sort of logging before or after the access to an object.</p>
<p>Let's say that in our game we have a <code>SpaceShip</code> object that has a <code>health</code> and a <code>damage</code> property, and we want to log every time the <code>fire()</code> method is called.</p>
<p>In that case we can use the Proxy Pattern to log every time the <code>fire()</code> method is called.</p>
<pre><code>abstract class SpaceShip {
  public abstract void fire();
}

// The concrete Space Ship that can actually fire something
class LaserSpaceShip implements SpaceShip {
  @override
  public void fire() {
    System.out.println("Firing");
  }
}

class SpaceShipProxy implements SpaceShip {
  private SpaceShip spaceShip;

  public SpaceShipProxy(SpaceShip spaceShip) {
    this.spaceShip = spaceShip;
  }

  @override
  public void fire() {
    System.out.println("Logging before firing");
    spaceShip.fire();
    System.out.println("Logging after firing");
  }
}
</code></pre>
<p>In this example the <code>SpaceShipProxy</code> class is the Proxy that logs every time the <code>fire()</code> method is called.</p>
<p>A quick example of how to use the Proxy Pattern:</p>
<pre><code>public static void main(String[] args) {
  SpaceShip spaceShip = new LaserSpaceShip();
  SpaceShip spaceShipProxy = new SpaceShipProxy(spaceShip);
  spaceShipProxy.fire();
}
</code></pre>
<h1>Behavioral Design Patterns</h1>
<p>The Behavioral Design Patterns are used to manage algorithms, relationships, and responsibilities between objects.</p>
<p>In this category of patterns there are the following patterns:</p>
<ul>
<li>Chain of Responsibility</li>
<li>Command</li>
<li>Iterator</li>
<li>Mediator</li>
<li>Memento</li>
<li>Observer</li>
<li>State</li>
<li>Strategy</li>
<li>Template Method</li>
<li>Visitor</li>
</ul>
<p>Let's see them.</p>
<h2>Chain of Responsibility</h2>
<p>The Chain of Responsability is a Behavioral Design Pattern that allows you to pass a request along a chain of handlers.</p>
<p>What that means?</p>
<p>It means that you can have a chain of objects that can handle a request, and the request is passed along the chain until one of the objects in the chain handles the request.</p>
<p>With this pattern I take the permission to pick another example that is not related to the <strong>SpaceShip Game</strong>...I know, I know, forgive me.</p>
<p>The most intuitive way to represent Chain of Responsability for me is with the concept of <code>middleware</code> in a web server.</p>
<p>Usually a middleware, as the name suggest, is a middle layer between a <em>request</em> and a <em>response</em> in a web server, so it's a set of one or more actions that are performed before the request is handled and a response is fired.</p>
<p>In a web server you can have multiple middlewares that handle the request, and the request is passed along the chain until one of the middlewares pass the middlware to the concrete request handler.</p>
<p>Let's image that between our request and response, in order, we have to:</p>
<ul>
<li>Log the request</li>
<li>Check if the user is authenticated</li>
<li>Check if the user has the permission to access the resource</li>
<li>Check if the user has the permission to perform the action</li>
</ul>
<p>In that case we can use the Chain of Responsability Pattern to handle the request.</p>
<pre><code>
class Request {}

abstract class Middleware {
  private Middleware next;

  public Middleware use(Middleware next) {
    this.next = next;
    return next;
  }

  public abstract boolean check(Request request);
}

class LogMiddleware extends Middleware {
  @override
  public boolean check(Request request) {
    System.out.println("Logging request");
    return next.check(request);
  }
}

class AuthMiddleware extends Middleware {
  @override
  public boolean check(Request request) {
    System.out.println("Checking authentication");
    return next.check(request);
  }
}

class PermissionMiddleware extends Middleware {
  @override
  public boolean check(Request request) {
    System.out.println("Checking permission");
    return next.check(request);
  }
}

class RoleMiddleware extends Middleware {
  @override
  public boolean check(Request request) {
    System.out.println("Checking role");
    return next.check(request);
  }
}
</code></pre>
<p>In this example the <code>LogMiddleware</code>, <code>AuthMiddleware</code>, <code>PermissionMiddleware</code>, and <code>RoleMiddleware</code> classes are the handlers that handle the request.</p>
<p>An example of how to use the Chain of Responsability Pattern:</p>
<pre><code>public static void main(String[] args) {
  Request request = new Request();
  Middleware middleware = new LogMiddleware();
  middleware
    .use(new AuthMiddleware())
    .use(new PermissionMiddleware())
    .use(new RoleMiddleware());

  middleware.check(request);
}
</code></pre>
<p>In this example the <code>LogMiddleware</code> class logs the request, the <code>AuthMiddleware</code> class checks if the user is authenticated, the <code>PermissionMiddleware</code> class checks if the user has the permission to access the resource, and the <code>RoleMiddleware</code> class checks if the user has the permission to perform the action.</p>
<p>So as you can see the "CoR" respects the Single Responsibility Principle, since each middleware has a single responsibility, and you can clearly define the order of execution of the middlewares, plus you can easily add or remove a middleware from the chain.</p>
<h2>Command</h2>
<p>The Command Pattern is a Behavioral Design Pattern that allows you to encapsulate a request as an object, thereby allowing you to parameterize clients with queues, delayes, and various operations.</p>
<p>The Command itself is usally just an interface with a single method:</p>
<pre><code>
interface Command {
  void run();
}
</code></pre>
<p>Then we can define concrete implementation of that interface for various kind of actions that we need to perform. In the case of the SpaceShip example let's says that we have some sort of cool interface to create a SpaceShip, so user can add various pieces to the SpaceShip like the kind of metal which the shape is built, the kind of weapon or the kind of driver.</p>
<pre><code>
class SpaceShip {
  private String metal;
  private String weapon;
  private String driver;

  public SpaceShip(String metal, String weapon, String driver) {
    this.metal = metal;
    this.weapon = weapon;
    this.driver = driver;
  }

  public void launch() {
    System.out.println("Launching SpaceShip with " + metal + " metal, " + weapon + " weapon and " + driver + " driver");
  }
}
```

For each of these actions we can create a concrete command:

```java
class SetMetalCommand implements Command {
  private SpaceShip spaceShip;
  private String metal;
  public SetMetalCommand(SpaceShip spaceShip, String metal) {
    this.spaceShip = spaceShip;
    this.metal = metal;
  }

  @override
  public void run() {
    spaceShip.setMetal(metal);
  }
}

class SetWeaponCommand implements Command {
  private SpaceShip spaceShip;
  private String weapon;
  public SetWeaponCommand(SpaceShip spaceShip, String weapon) {
    this.spaceShip = spaceShip;
    this.weapon = weapon;
  }

  @override
  public void run() {
    spaceShip.setWeapon(weapon);
  }
}

class SetDriverCommand implements Command {
  private SpaceShip spaceShip;
  private String driver;
  public SetDriverCommand(SpaceShip spaceShip, String driver) {
    this.spaceShip = spaceShip;
    this.driver = driver;
  }

  @override
  public void run() {
    spaceShip.setDriver(driver);
  }
}
</code></pre>
<blockquote>
<p>[!NOTE]
As you can see in this example is not the Command that do the logic of setting the metal, weapon or driver, but it's the <code>SpaceShip</code> class that has to do that, the Command just encapsulate the request to do that.</p>
</blockquote>
<p>Then we can create an <code>Invoker</code> class that will be responsible to execute the commands:</p>
<pre><code>class Invoker {
  private Command command;
  public void setCommand(Command command) {
    this.command = command;
  }

  public void executeCommand() {
    command.run();
  }
}
</code></pre>
<p>An example of how to use the Command Pattern:</p>
<pre><code>public static void main(String[] args) {
  SpaceShip spaceShip = new SpaceShip();
  Invoker invoker = new Invoker();

  invoker.setCommand(new SetMetalCommand(spaceShip, "Titanium"));
  invoker.executeCommand();

  invoker.setCommand(new SetWeaponCommand(spaceShip, "Laser"));
  invoker.executeCommand();

  invoker.setCommand(new SetDriverCommand(spaceShip, "John Doe"));
  invoker.executeCommand();
}
</code></pre>
<blockquote>
<p>[!NOTE]
In this example the "Client" of our application is the <code>main</code> method itself.</p>
</blockquote>
<p>With this Invoker we can also create a queue of commands to be executed later, or we can create a history of commands to be undone.</p>
<pre><code>
class Invoker {
  private List&lt;Command&gt; commandHistory = new ArrayList&lt;&gt;();
  public void setCommand(Command command) {
    this.commandHistory.add(command);
  }

  public void executeCommands() {
    for (Command command : commandHistory) {
      command.run();
    }
    commandHistory.clear();
  }

  public void undoLastCommand() {
    if (!commandHistory.isEmpty()) {
      commandHistory.remove(commandHistory.size() - 1);
    }
  }
}
</code></pre>
<p>This pattern is very useful when you want to decouple the object that invokes the operation from the one that knows how to perform it.</p>
<p>This will open up a world of endless possibility, like implementing a queue of commands, a history of commands to be undone, or even a remote control system.</p>
<p>So to be clear the process of <strong>applying the Command Pattern</strong> is:</p>
<ol>
<li>Define the Command interface with a single method.</li>
<li>Create concrete Command classes that implement the Command interface.</li>
<li>Identify (or create) classes that will act as <em>senders</em> of the commands.</li>
<li>Change the senders so they use Command objects instead of calling methods directly.</li>
</ol>
<blockquote>
<p>[!NOTE]
The Command Pattern is very useful in scenarios where you need to decouple the sender of a request from the receiver, or when you need to implement features like undo/redo, logging, or queuing of operations. But in our example we overcomplicated a simple scenario (creating a SpaceShip) just to show how the pattern works.</p>
</blockquote>
<h2>Iterator</h2>
<p>The Iterator Pattern is a Behavioral Design Pattern that allows you to traverse a collection of objects without exposing the underlying representation of the collection (list, stack, tree, etc..).</p>
<p>As hard as it might seem, the Iterator Pattern is very easy to understand and to implement. The key part is the "Collection" part, it's important to focus on that because the Iterator Pattern applies to collections of objects.</p>
<p>Collections are in each programming leanguage, and they are used to store multiple objects in a single object, such as an array, a list, a set, a map, a tree, etc...</p>
<p>The main problem with collections is that they have different ways to traverse (explore) the objects inside them.</p>
<p>The Iterataor Pattern in that case comes in handy since it provides a common Interface <code>Iteartor</code> that hase two simple methods that can be used to traverse the collection:</p>
<pre><code>interface Iterator&lt;T&gt; {
  boolean hasNext();
  T next();
}
</code></pre>
<p>The <code>hasNext()</code> method returns <code>true</code> if there are more elements in the collection, and the <code>next()</code> method returns the next element in the collection.</p>
<p>So now we can create a concrete implementation of the <code>Iterator</code> interface for our collection, let's say that in our application we are storing all the <code>SpaceShips</code> in the game, so the <code>Fleet</code> as a tree, since a fleet can have multiple fleets inside it.</p>
<pre><code>class SpaceShip {
  private String name;
  private String model;
  private int crew;
  private int maxSpeed;
  private String fuel;
  private int health;

  // constructor, getters and setters...
}
</code></pre>
<p>Now the <code>Fleet</code> class that will store all the <code>SpaceShips</code> in a tree structure <strong>MUST</strong> implements the <code>IterableCollection</code> interface that has the <code>createIterator()</code> method that returns an <code>Iterator</code> object.:</p>
<pre><code>interface IterableCollection&lt;T&gt; {
  Iterator&lt;T&gt; createIterator();
}
</code></pre>
<p>Now let's define the <code>Fleet</code> class:</p>
<pre><code>class Fleet implements IterableCollection&lt;SpaceShip&gt; {
  private List&lt;SpaceShip&gt; spaceShips = new ArrayList&lt;&gt;();
  private List&lt;Fleet&gt; fleets = new ArrayList&lt;&gt;();

  public void addSpaceShip(SpaceShip spaceShip) {
    spaceShips.add(spaceShip);
  }

  public void addFleet(Fleet fleet) {
    fleets.add(fleet);
  }

  @override
  public Iterator&lt;SpaceShip&gt; createIterator() {
    return new DepthFirstIterator(this);
  }

  public List&lt;SpaceShip&gt; getSpaceShips() {
    return spaceShips;
  }

  public List&lt;Fleet&gt; getFleets() {
    return fleets;
  }
}
</code></pre>
<p>Now based on our needs we can create as many as we want concrete implementation of the <code>Iterator</code> interface, for example we can create a <code>DepthFirstIterator</code> and a <code>BreadthFirstIterator</code> to traverse the tree in different ways.</p>
<pre><code>class DepthFirstIterator implements Iterator&lt;SpaceShip&gt; {
  private Stack&lt;Object&gt; stack = new Stack&lt;&gt;();
  private SpaceShip current;

  public DepthFirstIterator(Fleet fleet) {
    stack.push(fleet);
  }

  @Override
  public boolean hasNext() {
    while (!stack.isEmpty()) {
      Object top = stack.pop();
      if (top instanceof SpaceShip) {
        current = (SpaceShip) top;
        return true;
      } else if (top instanceof Fleet) {
        Fleet fleet = (Fleet) top;
        for (SpaceShip spaceShip : fleet.getSpaceShips()) {
          stack.push(spaceShip);
        }
        for (Fleet subFleet : fleet.getFleets()) {
          stack.push(subFleet);
        }
      }
    }
    return false;
  }

  @Override
  public SpaceShip next() {
    return current;
  }
}

class BreadthFirstIterator implements Iterator&lt;SpaceShip&gt; {
  private Queue&lt;Object&gt; queue = new LinkedList&lt;&gt;();
  private SpaceShip current;

  public BreadthFirstIterator(Fleet fleet) {
    queue.add(fleet);
  }

  @Override
  public boolean hasNext() {
    while (!queue.isEmpty()) {
      Object front = queue.poll();
      if (front instanceof SpaceShip) {
        current = (SpaceShip) front;
        return true;
      } else if (front instanceof Fleet) {
        Fleet fleet = (Fleet) front;
        for (SpaceShip spaceShip : fleet.getSpaceShips()) {
          queue.add(spaceShip);
        }
        for (Fleet subFleet : fleet.getFleets()) {
          queue.add(subFleet);
        }
      }
    }
    return false;
  }

  @Override
  public SpaceShip next() {
    return current;
  }
}
</code></pre>
<p>Now we can use both the <code>DepthFirstIterator</code> and the <code>BreadthFirstIterator</code> to traverse the <code>Fleet</code> in different ways.</p>
<pre><code>public static void main(String[] args) {
  Fleet fleet = new Fleet();
  fleet.addSpaceShip(new SpaceShip("Enterprise", "NCC-1701", 430, 9500, "Dilithium", 100));
  fleet.addSpaceShip(new SpaceShip("Defiant", "NX-74205", 50, 9000, "Antimatter", 100));

  Fleet subFleet = new Fleet();
  subFleet.addSpaceShip(new SpaceShip("Voyager", "NCC-74656", 150, 9000, "Dilithium", 100));
  fleet.addFleet(subFleet);

  System.out.println("Depth First Traversal:");
  Iterator&lt;SpaceShip&gt; depthFirstIterator = fleet.createIterator();
  while (depthFirstIterator.hasNext()) {
    SpaceShip ship = depthFirstIterator.next();
    System.out.println(" - " + ship.getName());
  }

  System.out.println("\nBreadth First Traversal:");
  Iterator&lt;SpaceShip&gt; breadthFirstIterator = new BreadthFirstIterator(fleet);
  while (breadthFirstIterator.hasNext()) {
    SpaceShip ship = breadthFirstIterator.next();
    System.out.println(" - " + ship.getName());
  }
}
</code></pre>
<h2>Mediator</h2>
<p>Mediator is a behavioral design pattern that allows you to reduce the chaotic dependencies between objects. The pattern restricts direct communications between the objects and forces them to collaborate only via a mediator object.</p>
<p>The Mediator Pattern try to solves this issue by introducing a new Mediator Object that will handle the communication and the interactions between the objects.</p>
<p>The Mediator object is a simple interface that most of the times has only one method, that is the <code>notify()</code> method.</p>
<pre><code>interface Mediator {
  void notify(Object sender, Object event);
}
</code></pre>
<p>Then we can create as many concrete implementation of the <code>Mediator</code> interface as we want, based on our needs.</p>
<p>The concrete implementation of the <code>Mediator</code> are a bit more complex and they depends on the use case. Usually a concrete mediator class has all the dependencies of the objects that it has to mediate.</p>
<p>The objects that needs to mediate needs to have a reference of the <code>Mediator</code> interface (not the concrete mediator), this reference is usually passed in the constructor of the object and it will be used to notify the mediator when something happens.</p>
<p>Let's see an example with the SpaceShip game, let's say that we have a <code>SpaceShip</code> class that has a <code>fire()</code> method and a <code>takeDamage()</code> method, and we want to notify the <code>Fleet</code> when a <code>SpaceShip</code> fires or takes damage.</p>
<pre><code>class SpaceShip {
  private String name;
  private Mediator mediator;

  public SpaceShip(String name, Mediator mediator) {
    this.name = name;
    this.mediator = mediator;
  }

  public void fire() {
    System.out.println(name + " is firing");
    mediator.notify(this, "fire");
  }

  public void takeDamage(int damage) {
    System.out.println(name + " is taking " + damage + " damage");
    mediator.notify(this, "takeDamage");
  }
}
</code></pre>
<pre><code>class FleetMediator implements Mediator {
  private List&lt;SpaceShip&gt; spaceShips;

  public FleetMediator(List&lt;SpaceShip&gt; spaceShips) {
    this.spaceShips = spaceShips;
  }

  @override
  public void notify(Object sender, Object event) {
    if (event.equals("fire")) {
      System.out.println("FleetMediator: " + ((SpaceShip) sender).getName() + " has fired");
    } else if (event.equals("takeDamage")) {
      System.out.println("FleetMediator: " + ((SpaceShip) sender).getName() + " has taken damage");
    }
  }
}
</code></pre>
<p>An example of how to use the Mediator Pattern:</p>
<pre><code>public static void main(String[] args) {
  List&lt;SpaceShip&gt; fleet = new ArrayList&lt;&gt;();
  FleetMediator fleetMediator = new FleetMediator(fleet);

  SpaceShip enterprise = new SpaceShip("Enterprise", fleetMediator);
  SpaceShip defiant = new SpaceShip("Defiant", fleetMediator);
  fleet.add(enterprise);
  fleet.add(defiant);

  enterprise.fire();
  defiant.takeDamage(50);
}
</code></pre>
<p>This is a very basic example, leet's see a more complex one. Let's pretend we have to handle a chat room where multiple users can send messages to each other.</p>
<pre><code>class User {
  private String name;
  private Mediator mediator;

  public User(String name, Mediator mediator) {
    this.name = name;
    this.mediator = mediator;
  }

  public String getName() {
    return name;
  }

  public void sendMessage(String message) {
    System.out.println(name + " is sending message: " + message);
    mediator.notify(this, message);
  }
}

class ChatRoom implements Mediator {
  private List&lt;User&gt; users;

  public ChatRoom() {
    this.users = new ArrayList&lt;&gt;();
  }

  public void addUser(User user) {
    users.add(user);
  }

  @override
  public void notify(Object sender, Object event) {
    for (User user : users) {
      if (user != sender) {
        System.out.println(user.getName() + " received message: " + event);
      }
    }
  }
}
</code></pre>
<p>An example of how to use the Mediator Pattern in a chat room:</p>
<pre><code>public static void main(String[] args) {
  ChatRoom chatRoom = new ChatRoom(); // the mediator

  User alice = new User("Alice", chatRoom);
  User bob = new User("Bob", chatRoom);
  chatRoom.addUser(alice);
  chatRoom.addUser(bob);

  alice.sendMessage("Hello Bob!"); // The user do the concrete action, but the mediator handle the communication
  bob.sendMessage("Hi Alice!");
}
</code></pre>
<h2>Memento</h2>
<p>Memento is a behavioral design pattern that allows you to capture and externalize an object's internal state so that the object can be restored to this state later, without violating encapsulation.</p>
<p>So basically the Memento Pattern is used to implement the undo/redo functionality in an application.</p>
<p>We have three main components in the Memento Pattern:</p>
<ol>
<li>The Originator: the object whose state we want to save and restore, and is also the one who generates the state.</li>
<li>The Memento: the object that stores the internal past snapshots of state of the Originator, without exposing its implementation details, so that the Originator can restore its state from the Memento.</li>
<li>The Caretaker: the object that is responsible for storing and restoring the Mementos, often is used with the Command Pattern and the Command object is the Caretaker, its purpose is to create backups of the state, and undo/redo functionality.</li>
</ol>
<p>Let's see an example with the SpaceShip game, let's say that we have a <code>SpaceShip</code> class that has a <code>health</code> property, and we want to save the state of the <code>SpaceShip</code> before taking damage, so that we can restore it later.</p>
<pre><code>// In this case SpaceShip is the Originator, the one who holds the state that is the health in our case
class SpaceShip {
    private int health;

    public SpaceShip(int health) {
        this.health = health;
    }

    public void setHealth(int health) {
        this.health = health;
    }

    public int getHealth() {
        return health;
    }

    public void restore(SpaceShipMemento memento) {
        this.health = memento.getHealth();
    }

    // Creates a memento with current state
    public SpaceShipMemento save() {
        return new SpaceShipMemento(health);
    }

    // Inner Memento class that stores the past state of the SpaceShip
    // This is used so the caregiver doesnt have access to the internal state of the SpaceShip
    public class SpaceShipMemento {
        private final int health;

        public SpaceShipMemento(int health) {
            this.health = health;
        }

        public int getHealth() {
            return health;
        }
    }
}


// Store previous mementos state and eventually restore them
class Caretaker {
    private Stack&lt;SpaceShip.SpaceShipMemento&gt; history = new Stack&lt;&gt;();

    public void save(SpaceShip spaceShip) {
        history.push(spaceShip.save());
    }

    public void undo(SpaceShip spaceShip) {
        if (!history.isEmpty()) {
            SpaceShip.SpaceShipMemento memento = history.pop();
            spaceShip.restore(memento);
        }
    }
}
</code></pre>
<h2>Observer</h2>
<p>Observer is a behavioral design pattern that lets you define a subscription mechanism to notify multiple objects about any events that happen to the object they’re observing.</p>
<p>The Observer Pattern is used when you have a one-to-many relationship between objects, so when one object changes state, all its dependents are notified and updated automatically. This is a very common scenario so let's see how can we integrate it in the SpaceShip game.</p>
<p>Let's say that we have a <code>Fleet</code> class that has multiple <code>SpaceShip</code> objects, and we want to notify all the <code>SpaceShip</code> objects when the <code>Fleet</code> changes state, for example when a new <code>SpaceShip</code> is added to the <code>Fleet</code>.</p>
<pre><code>interface Observer {
  void update(String message);
}

// Handy interface for the Subject, the one that notify all the observers
interface Subject {
  void attach(Observer observer); // attach a new observer (subscriber) to the subject
  void detach(Observer observer); // detach an observer (subscriber) from the subject
  void notifyObservers(String message); // notify all the observers (subscribers) about an event
}

// In this case the Fleet is the Publisher (or Subject) that notify all the SpaceShip (Observers) when something happens
class Fleet implements Subject {
  private List&lt;Observer&gt; observers = new ArrayList&lt;&gt;();
  private List&lt;SpaceShip&gt; spaceShips = new ArrayList&lt;&gt;(); // The main state of the Fleet

  public void addSpaceShip(SpaceShip spaceShip) {
    spaceShips.add(spaceShip);
    // Notify all observers about the new SpaceShip
    notifyObservers("New SpaceShip added: " + spaceShip.getName());
  }

  public void importantFleetEvent(String event) {
    // Notify all observers about the important event
    notifyObservers("Important Fleet Event: " + event);
  }

  public void attach(Observer observer) {
    observers.add(observer);
  }

  public void detach(Observer observer) {
    observers.remove(observer);
  }

  public void notifyObservers(String message) {
    for (Observer observer : observers) {
      observer.update(message);
    }
  }
}

// Its the concrete Subscriber (Observer) that wants to be notified when something happens in the Publisher (Subject)
class SpaceShip implements Observer {
  private String name;

  public SpaceShip(String name) {
    this.name = name;
  }

  public void update(String message) {
    // can perform something when receiving the notification from the publisher (Fleet)
    System.out.println(name + " received message: " + message);
  }
}
</code></pre>
<p>An example of how to use the Observer Pattern:</p>
<pre><code>public static void main(String[] args) {
  Fleet fleet = new Fleet();
  SpaceShip ship1 = new SpaceShip("Ship 1");
  SpaceShip ship2 = new SpaceShip("Ship 2");

  fleet.attach(ship1);
  fleet.attach(ship2);

  fleet.addSpaceShip(new SpaceShip("Ship 3"));
  fleet.importantFleetEvent("Enemy fleet detected!");
}
</code></pre>
<p>Ofc also other entites can be attached to the <code>Fleet</code> and be notified when something happens, for example a <code>FleetCommander</code> class that wants to be notified when a new <code>SpaceShip</code> is added to the <code>Fleet</code>.</p>
<pre><code>class FleetCommander implements Observer {
  private String name;

  public FleetCommander(String name) {
    this.name = name;
  }

  public void update(String message) {
    // can perform something when receiving the notification from the publisher (Fleet)
    System.out.println(name + " received message: " + message);
  }
}
</code></pre>
<p>An example of how to use the Observer Pattern with the <code>FleetCommander</code>:</p>
<pre><code>public static void main(String[] args) {
  Fleet fleet = new Fleet();
  SpaceShip ship1 = new SpaceShip("Ship 1");
  FleetCommander commander = new FleetCommander("Commander");

  fleet.attach(ship1);
  fleet.attach(commander);

  fleet.addSpaceShip(new SpaceShip("Ship 2"));
  fleet.importantFleetEvent("Enemy fleet detected!");
}
</code></pre>
<h2>State</h2>
<p>State is a behavioral design pattern that allows an object to alter its behavior when its internal state changes. The object will appear to change its class.</p>
<p>Usually programs can be in different states, and based on the state the program can behave differently. Instead of handling the state with a lot of <code>if</code> or <code>switch</code> statements, we can use the State Pattern to handle the state in a more elegant way and scalable way.</p>
<p>We can define a <code>State</code> interface that has a method for each action that can be performed in the different states.</p>
<pre><code>interface State {
  void handle();
}
</code></pre>
<p>For example in our SpaceShip game we can have a <code>SpaceShip</code> class that can be in different states, such as <code>Idle</code>, <code>Flying</code>, <code>Attacking</code>, and <code>Damaged</code>.</p>
<pre><code>class SpaceShip {
  private State state;

  public SpaceShip() {
    this.state = new IdleState(this); // initial state
  }

  // logic to change the state
  public void setState(State state) {
    this.state = state;
  }

  // method to handle the state based on the current one
  // in our eample this will print something
  // but in a real game this will perform some concrete action
  public void handle() {
    state.handle();
  }
}
</code></pre>
<p>Then we can create concrete implementation of the <code>State</code> interface for each state.</p>
<pre><code>class IdleState implements State {
  private SpaceShip spaceShip;

  public IdleState(SpaceShip spaceShip) {
    this.spaceShip = spaceShip;
  }

  public void handle() {
    System.out.println("SpaceShip is idle.");
  }
}

class FlyingState implements State {
  private SpaceShip spaceShip;

  public FlyingState(SpaceShip spaceShip) {
    this.spaceShip = spaceShip;
  }

  public void handle() {
    System.out.println("SpaceShip is flying.");
  }
}

class AttackingState implements State {
  private SpaceShip spaceShip;

  public AttackingState(SpaceShip spaceShip) {
    this.spaceShip = spaceShip;
  }

  public void handle() {
    System.out.println("SpaceShip is attacking.");
  }
}

class DamagedState implements State {
  private SpaceShip spaceShip;

  public DamagedState(SpaceShip spaceShip) {
    this.spaceShip = spaceShip;
  }

  public void handle() {
    System.out.println("SpaceShip is damaged.");
  }
}

</code></pre>
<p>A more complex example would be to have the state directly tells if a <code>SpaceShip</code> can perform a specific action or not, for example if the <code>SpaceShip</code> is in the <code>DamagedState</code> it cannot <code>fly()</code> or <code>attack()</code>, but it can only <code>repair()</code>.</p>
<pre><code>interface State {
  void fly();
  void attack();
  void repair();
}
</code></pre>
<p>Now let's define the <code>SpaceShip</code> class:</p>
<pre><code>class SpaceShip {
  private State state;

  public SpaceShip() {
    this.state = new IdleState(this); // initial state
  }

  // logic to change the state
  public void setState(State state) {
    this.state = state;
  }

 // It's not the spaceship that handles the logic of the action, but it's the current state that handles it
 // so the system can behave differently based on the current state
  public void fly() {
    state.fly();
  }

  public void attack() {
    state.attack();
  }

  public void repair() {
    state.repair();
  }
}
</code></pre>
<p>Then we can create concrete implementation of the <code>State</code> interface for each state.</p>
<pre><code>class IdleState implements State {
  private SpaceShip spaceShip;

  public IdleState(SpaceShip spaceShip) {
    this.spaceShip = spaceShip;
  }
  public void fly() {
    System.out.println("SpaceShip is flying.");
    spaceShip.setState(new FlyingState(spaceShip));
  }

  public void attack() {
    System.out.println("SpaceShip is attacking.");
    spaceShip.setState(new AttackingState(spaceShip));
  }

  public void repair() {
    System.out.println("SpaceShip is already in good condition.");
  }
}

// ... other states with different logic implementation
</code></pre>
<h2>Strategy</h2>
<p>The Strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. This pattern lets the algorithm vary independently from clients that use it.</p>
<p>In our SpaceShip example, we could use the Strategy pattern to define different flying behaviors.</p>
<pre><code>// Strategy contract
interface FlyStrategy {
  void fly();
}

// Concrete strategies implementing the FlyStrategy interface
class FlyWithWings implements FlyStrategy {
  public void fly() {
    System.out.println("Flying with wings!");
  }
}

class FlyWithFuel implements FlyStrategy {
  public void fly() {
    System.out.println("Flying with fuel!");
  }
}

// This calss is the context. Is the one that use the strategy
// and communicates with its object only via the strategy interface
class SpaceShip {
  private FlyStrategy flyStrategy;

  public SpaceShip(FlyStrategy flyStrategy) {
    this.flyStrategy = flyStrategy;
  }

  public void performFly() {
    flyStrategy.fly();
  }
}
</code></pre>
<p>And then we can use it like this:</p>
<pre><code>// In this case is the client of the strategy pattern
public static void main(String[] args) {
  SpaceShip birdShip = new SpaceShip(new FlyWithWings());
  birdShip.performFly(); // Output: Flying with wings!

  SpaceShip rocketShip = new SpaceShip(new FlyWithFuel());
  rocketShip.performFly(); // Output: Flying with fuel!
}
</code></pre>
<h2>Template Method</h2>
<p>The teamplate method is a behavioral design pattern that defines the skeleton of an algorithm in the superclass but lets subclasses override specific steps of the algorithm without changing its structure.</p>
<p>This pattern is used when several classes uses the same algorithm, but with some variations in specific steps of the algorithm. So instead of duplicating the algorithm in each class, we can define the algorithm in a superclass and let the subclasses override the specific steps.</p>
<p>In our SpaceShip example, we could use the Template Method pattern to define a general algorithm for attacking, but let subclasses define specific attack strategies.</p>
<pre><code>abstract class SpaceShip {
  // Template method defining the skeleton of the algorithm
  public final void attack() {
    prepareForAttack();
    executeAttack();
    retreat();
  }

  protected abstract void prepareForAttack(); // Step to be implemented by subclasses
  protected abstract void executeAttack(); // Step to be implemented by subclasses

  private void retreat() { // Common step for all subclasses
    System.out.println("Retreating to safe distance.");
  }
}

// The concrete classes implement the specific steps of the algorithm
// The benefit is that those SpaceShips doesn't have to implement the whole attack algorithm
// just the part that is different
public class LaserSpaceShip extends SpaceShip {
  @Override
  protected void prepareForAttack() {
    System.out.println("Charging laser weapons.");
  }

  @Override
  protected void executeAttack() {
    System.out.println("Firing laser beams!");
  }
}

public class PlasmaSpaceShip extends SpaceShip {
  @Override
  protected void prepareForAttack() {
    System.out.println("Preparing plasma weapons.");
  }

  @Override
  protected void executeAttack() {
    System.out.println("Firing plasma blasts!");
  }
}

</code></pre>
<p>Now let's see how to use the Template Method pattern:</p>
<pre><code>public static void main(String[] args) {
  SpaceShip laserShip = new LaserSpaceShip();
  laserShip.attack();

  SpaceShip plasmaShip = new PlasmaSpaceShip();
  plasmaShip.attack();
}
</code></pre>
<h2>Visitor</h2>
<p>The Visitor pattern is a behavioral design pattern that lets you separate algorithms from the objects on which they operate. It allows you to add new operations to existing object structures without modifying the structures.</p>
<p>The Visitor pattern is used when you have a complex object structure, and you want to perform operations on the objects in the structure without changing their classes. Instead of adding methods to the classes, you create a visitor class that implements the operations.</p>
<pre><code>interface Visitor {
  void visit(SpaceShip spaceShip);
  void visit(Fleet fleet);
}

interface Element {
  void accept(Visitor visitor);
}

class SpaceShip implements Element {
  private String name;

  public SpaceShip(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }

  public void accept(Visitor visitor) {
    visitor.visit(this);
  }
}

class Fleet implements Element {
  private List&lt;Element&gt; elements = new ArrayList&lt;&gt;();

  public void addElement(Element element) {
    elements.add(element);
  }

  public List&lt;Element&gt; getElements() {
    return elements;
  }

  public void accept(Visitor visitor) {
    for (Element element : elements) {
      element.accept(visitor);
    }
    visitor.visit(this);
  }
}

class FleetStatusVisitor implements Visitor {
  public void visit(SpaceShip spaceShip) {
    System.out.println("Visiting SpaceShip: " + spaceShip.getName());
  }

  public void visit(Fleet fleet) {
    System.out.println("Visiting Fleet with " + fleet.getElements().size() + " elements.");
  }
}

class FleetRepairVisitor implements Visitor {
  public void visit(SpaceShip spaceShip) {
    System.out.println("Repairing SpaceShip: " + spaceShip.getName());
  }

  public void visit(Fleet fleet) {
    System.out.println("Repairing Fleet with " + fleet.getElements().size() + " elements.");
  }
}

public static void main(String[] args) {
  Fleet fleet = new Fleet();
  fleet.addElement(new SpaceShip("Enterprise"));
  fleet.addElement(new SpaceShip("Defiant"));

  Fleet subFleet = new Fleet();
  subFleet.addElement(new SpaceShip("Voyager"));
  fleet.addElement(subFleet);

  FleetStatusVisitor statusVisitor = new FleetStatusVisitor();
  fleet.accept(statusVisitor);

  FleetRepairVisitor repairVisitor = new FleetRepairVisitor();
  fleet.accept(repairVisitor);
}
</code></pre>
]]></content>
        <author>
            <name>fres</name>
            <uri>https://fres.space</uri>
        </author>
        <published>2025-03-12T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Authentication System in Hono]]></title>
        <id>https://fres.space/posts/authentication-system-hono/</id>
        <link href="https://fres.space/posts/authentication-system-hono/"/>
        <updated>2024-12-27T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Learn how to implement email/password authentication, JWT tokens, email verification, and password reset functionality from scratch.]]></summary>
        <content type="html"><![CDATA[<p><img src="https://5yyithvls1.ufs.sh/f/3nsI94TDxXoGglNkn0JwWvMDUV14dEPGi239taOR50FusABm" alt="" /></p>
<p>::github{repo="fres-sudo/hono-auth"}</p>
<h2>Introduction</h2>
<p>In this article I'm will try my best to explain to you about the creation from the ground up of a complete authentication system for your next successful application.</p>
<p>I'm sorry for any grammatical errors, this is my first article and I'm not english mother tongue.</p>
<h3>Functionalities</h3>
<p>Here it is a quick break down of what functionalities your app will have at the end of the article:</p>
<ul>
<li>Email and password authentication</li>
<li>JWT Access and Refresh Token System</li>
<li>Email Verification</li>
<li>Forgot password, OTP code verification, Reset password</li>
</ul>
<h3>Technologies</h3>
<p>Those are the main technologies and libraries that you will need to spin up this simple application:</p>
<ul>
<li>Typescript, basically JS but a bit better,</li>
<li>Hono, a ligthweigth Javascript framework to build fast web application,</li>
<li>Drizzle ORM,</li>
<li>Postgres SQL,</li>
<li>Zod for DTOs,</li>
<li><code>tsrynge</code> an easy library for Dependence Injection in Typescript,</li>
</ul>
<p>Notice that you can basically use what technologies you prefer, those are just based on my personal preference, you don't have to stick with them, but also notice that if you choose to go with something else you will have to make some changes at your code.</p>
<h3>Architecture Overview</h3>
<p>The architecture is heavy inspired by this <a href="https://github.com/Rykuno/TofuStack">awesome project</a>, I'll just mention more or less what the creator said in his introduction.</p>
<p>There are a few popular architectures for structuring backends. Technical, Onion, DDD, VSA, and the list goes on.</p>
<h4>Folder Structure</h4>
<ul>
<li>
<p><strong>controllers</strong> - Responsible for routing requests</p>
</li>
<li>
<p><strong>services</strong> - Responsible for handling business logic.</p>
</li>
<li>
<p><strong>repositories</strong> - Responsible for retrieving and
storing data.</p>
</li>
<li>
<p><strong>infrastructure</strong> - Handles the implementation of external services or backend operations.</p>
</li>
<li>
<p><strong>middleware</strong> - Middlware our request router is responsible for handling.</p>
</li>
<li>
<p><strong>providers</strong> - Injectable services</p>
</li>
<li>
<p><strong>dtos</strong> - Data Transfer Objects (DTOs) are used to define the shape of data that is passed.</p>
</li>
</ul>
<h4>File Naming</h4>
<p>Each file of the project is postfixed with its architectural type(e.g. <code>iam.service.ts</code>). This allows
us to easily reorganize the folder structure to suite a different architecture pattern if the domain becomes more complex.</p>
<p>For example, if you want to group folders by domain(DDD), you simply drag and drop all related files to that folder.</p>
<pre><code>└── events/
    ├── events.controller.ts
    ├── events.service.ts
    └── events.repository.ts
</code></pre>
<h3>Why?</h3>
<p>I am making this article to help people struggling with finding a resource that will help them to spin up a complete authentication system, often the guides and video tutorial online not includes all the functionalities that I will show you in this article.</p>
<p>The claim is to have a place to get a look when you feel lost while writing your authentication system.</p>
<p>This IS NOT the perfect authentication system, this is just <em>mine</em> authentication system.</p>
<p>Authentication is usually a non-trivial area, so use my implementation at your own risk.</p>
<h3>Who?</h3>
<p>This guide is for developers that already know the basics of Javascript or Typescript, you don't need to know any JS framework, if you already play with Express.js or something like that you will probably will understand more, but it is not required.</p>
<p>Of course basic understanding of how an HTTP server works and the interaction between client and server is mandatory, also what is a RESTful API and how it works.</p>
<p>In this article I will not go in the details of the architectural implementation of the system, or how to install the software, it will use <code>bun</code> as package manager, but you can use whatever you prefer, it will change quite nothing.</p>
<p>Also a basic understand of Docker is better to complete understand the course.</p>
<h3>Where?</h3>
<p>No worries, you will find all the code in <a href="https://github.com/fres-sudo/hono-auth">this Github repository</a>. If you will find this article useful I will highly appreciate a Github ⭐ I still highly suggest you to follow</p>
<h2>Getting Started</h2>
<p>To get started right we first need to create a new project.</p>
<pre><code>bun create hono@latest
</code></pre>
<p>This command will guide you through a wizard for the creation of your bun application, the process for other packer manager is more or the less the same.</p>
<p>The first thing you will get asked is to choose a target directory, this means that if you are already in your project directory you just need to type <code>.</code>, otherwise just type the name of the folder of the project, I will use <code>hono-auth</code>, you can choose your own.</p>
<p>After that you will prompted to choose from a template, this is the most important part, for this guide I will choose bun, this will create a basic <code>src/index.ts</code> file, that is the <em>entry point</em> of our new application. It will also generate other files, such as the configuration of Typescript in <code>tsconfig.json</code> and the most important, the <code>package.json</code>, in here we can see that bun create a simple script for run our app.</p>
<pre><code>  "scripts": {
    "dev": "bun run --hot src/index.ts"
  }
</code></pre>
<p>Notice that if you choose other template for other kind of project your output would be slightly different, choose what you need!</p>
<p>If he ask you to install the project dependencies just say yes, and for the package manger just choose what you prefer, as I said, I'll stick with bun.</p>
<p>So if we run our app with <code>bun dev</code> and we try to call the <code>localhost:3000/</code> endpoint we should get some feedback.</p>
<p>I will use <code>httppie</code> that is just a CLI tool that can make you make request to endpoints, but you can use Postman or whatever you prefer.</p>
<p>so your output would be:</p>
<pre><code>Hello Hono!
</code></pre>
<p>or something like that.</p>
<h3>Dependencies</h3>
<p>Before even touch any code, let's add some packages to our project so we don't have to do it later on the fly.</p>
<p>Just type in the terminal:</p>
<pre><code>bun add tsyringe drizzle-kit drizzle-orm drizzle-zod zod reflect-metadata typescript arctic postgres nodemailer hono-rate-limiter @hono/zod-validator @paralleldrive/cuid2
</code></pre>
<p>Those are the main dependencies for this project, you just add those and you are ready to go.</p>
<h3>Setup</h3>
<p>Before starting there will be a quite long session of setup before starting. I'll break down the major steps for you, be sure to follows every single step to not get lost.</p>
<ul>
<li>Docker Setup</li>
<li>Drizzle Setup</li>
<li>Configuration Setup</li>
<li>Dipendence Injection Setup</li>
</ul>
<p>Let's get started.</p>
<h4>Docker Setup</h4>
<p>This step <em>is not necessary</em> but I personally highly reccomend to follow up and use docker, to avoid any problems related to your machine.</p>
<p>I will not explain the reason to choose docker, just do it, and you will not regret it! Aside from jokes, Docker will help us to ensure that we all got the same setup and you work on an isolated environment.</p>
<p>So first thing first you might need to install Docker (and <a href="https://docs.docker.com/compose/install/">Docker Compose</a>) on you machine, you can find the installation <a href="https://www.docker.com/">here</a>, if you are new to docker I will suggest you to download also the desktop version if is your first time with docker so you can visually see what is going on.</p>
<h5>Dockerfile</h5>
<p>So the first thing we need in our <strong>isolated environment</strong> is obviously our app and our dependencies, so we can create an entry point for docker to download it and serve to us.</p>
<p>This will be accomplished by creating a <code>Dockerfile</code> in our root directory, so in my case it will be <code>hono-auth/Dockerfile</code>:</p>
<pre><code>
FROM oven/bun:1.0.35

WORKDIR /home/bun/app

COPY ./package.json .

RUN bun install

COPY . .

CMD [ "bun", "run", "dev" ]

</code></pre>
<p>So basically here we are downloading bun, setting up out work directory, copying the package.json with all the necessary information and then install the dependencies in the environment, after that we're also telling docker that it has to execute <code>bun run dev</code>.</p>
<p>&lt;a name="docker-compose"&gt;&lt;/a&gt;</p>
<h5>Docker Compose</h5>
<p>Now that we have our entry- point, since we will have two different containers, running at the same time, we have to define a <strong>Docker Compose</strong> file, to handle the two container and the communication between the two.</p>
<p>For doing that we will need to create <code>docker-compose.yaml</code> file in out root directory.</p>
<pre><code>services:
  app:
    container_name: hono-app
    build:
      dockerfile: Dockerfile
    depends_on:
      - postgres
    env_file:
      - .env
    ports:
      - 3000:3000
    restart: always
    networks:
      - app-network
  postgres:
    container_name: db
    image: postgres:latest
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: postgres
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

volumes:
  postgres_data:
</code></pre>
<p>So as you can see we are defining 2 differnet services:</p>
<ul>
<li>
<p><strong>app</strong> : this will be the hono app, and it has a docker file, that is the file that we created earlier, it obviously depends on the <code>db</code>, since we need first the db to make the app starts, we define the <code>.env</code> file with all our secrets, the ports that we are using in the project and the port we want to expose on docker, and of course the network. The network is just a bridge that ensure the communication between 2 or more services (or containers).</p>
</li>
<li>
<p><strong>db</strong> : this is the postgres instance that we will use as databse in our app, the paramteres are quite the same and self explanatory.</p>
</li>
</ul>
<p>Once we setup everything we can now define some scripts to effectively runs these 2 containers.</p>
<p>so in the <code>package.josn</code> we can define:</p>
<pre><code>"scripts": {
    "dev": "bun run --hot src/index.ts",
    "docker:up": "docker-compose up -d",
    "docker:build": "docker-compose up -d --build",
  }
</code></pre>
<h4>Drizzle Setup</h4>
<p>Even if Drizzle is a <em>fast</em> ORM, it will require a small setup, nothing too crazy, don't worry. For more detailed introduction to setup Drizzle ORM I higly suggest you to check out their official <a href="https://orm.drizzle.team/docs/get-started/postgresql-new">documentation</a> that is very great.</p>
<h5>Setup Env variables</h5>
<p>If you are using external database, like Neon, Supabase, ecc... Feel free to put your url as env variable.</p>
<p>To connect to the PostgreSQL database, you need to provide the database URL. The URL format is:</p>
<pre><code>postgres://&lt;user&gt;:&lt;password&gt;@&lt;host&gt;:&lt;port&gt;/&lt;database&gt;
</code></pre>
<p>So create a <code>.env</code> file at root of the application and fill with the values you choose in the docker compose, in our case is:</p>
<pre><code>DATABASE_URL=postgresql://postgres:postgres@postgres:5432/postgres
</code></pre>
<h6>Configuration File</h6>
<p>For the next setup we also need to define some structure of out environment variables, so we can do that as follows.</p>
<p>Since I'm using <code>bun</code>, the engine gives to me some useful API to retrive environment variables, without the need of external packages.</p>
<p>Please notice that if you are using other engine, we will need some adjustment and most likely also using a 3rd part package to interact with env variables.</p>
<p>In <code>bun</code> we can retrive an environment variable in some way, for personal preference I will use:</p>
<pre><code>process.env.[ENV_VARIABLE_NAME]
</code></pre>
<p>For a better structured setup, create a <code>config.type.ts</code> under <code>src/types/</code>.</p>
<pre><code>// src/types/config.type.ts

export const config: Config = {
 isProduction: process.env.NODE_ENV === "production",
 api: {
  origin: process.env.ORIGIN ?? "",
 },
 postgres: {
  url: process.env.DATABASE_URL ?? "",
 },
};

interface Config {
 isProduction: boolean;
 api: ApiConfig;
 postgres: PostgresConfig;
}

interface ApiConfig {
 origin: string;
}

interface PostgresConfig {
 url: string;
}
</code></pre>
<p>As you can see I also add a quite useful environment variable that is:</p>
<pre><code>ORIGIN=http://localhost:3000 //3000 is the port we define in the docker-compose.yaml file
</code></pre>
<p>Since now the project is local, we just use <code>localhost</code> but when you will deploy it you will put here your correct url.</p>
<h5>Drizzle Configuration</h5>
<p>For correctly setup drizzle we need to define a configuration file, that will be placed in the root of our application, so in this case it will be <code>hono-auth/drizzle.config.ts</code>, this file will contains all the necessary information for drizzle to spin up.</p>
<pre><code>// drizzle.config.ts
import type { Config } from "drizzle-kit";
import { config } from "./src/types/config.type";

export default {
 out: "./src/infrastructure/database/migrations",
 schema: "./src/infrastructure/database/tables/index.ts",
 breakpoints: false,
 strict: true,
 dialect: "postgresql",
 dbCredentials: {
  url: config.postgres.localUrl,
 },
 migrations: {
  table: "migrations",
  schema: "public",
 },
 verbose: true,
} satisfies Config;
</code></pre>
<p>As you can see a lot of stuff are going on here, but let's break down the important parts real quick.</p>
<ul>
<li><strong>out</strong> is the output directory where the migrations will be localted, you can choose whatever you want;</li>
<li><strong>schema</strong> is the imporant file where drizzle will pull all the schemas of your database and will reflect your postgres instance accordingly</li>
</ul>
<h5>Drizzle Entry Point</h5>
<p>The Drizzle entry point is basically where your app tells drizzle to connect with databse, in our case it will be located under.</p>
<p>In our case I prefer to locate it under <code>src/infrastructure/database/index.ts</code>, the file contente of <code>index.ts</code> will be:</p>
<pre><code>// src/infrastructure/database/index.ts
import { drizzle } from "drizzle-orm/postgres-js";
import postgres from "postgres";
import * as schema from "./tables";
import { config } from "../../types/config.type";

export const client = postgres(config.postgres.url, { max: 10 });
export const db = drizzle(client, { schema });
</code></pre>
<p>So far our infrastructure structure looks like this:</p>
<pre><code>└── infrastructure/
    └── database/
     ├── utils.ts
     ├── index.ts
     └── migrations/

</code></pre>
<p>As you can see there are also some files that we didn't meet so far. Let's break it down:</p>
<pre><code>//src/infrastructure/database/utils.ts
import { HTTPException } from "hono/http-exception";

export const takeFirst = &lt;T&gt;(values: T[]): T | null =&gt; {
 if (values.length === 0) return null;
 return values[0]!;
};

export const takeFirstOrThrow = &lt;T&gt;(values: T[]): T =&gt; {
 if (values.length === 0)
  throw new HTTPException(404, {
   message: "Resource not found",
  });
 return values[0]!;
};
</code></pre>
<p>This file contains two crucial function that we will be using a lot in our queries.</p>
<p>The migration is the directory that we pointed in the index.ts file, and it will contains all our migration <code>.sql</code> file for out database.</p>
<h3>Dependencies Injection Setup</h3>
<p>As I said before for dependency injection, I'm going to use <code>tsyringe</code> but you can actually use whatever you want.</p>
<p>If you will use both <code>bun</code> and <code>tsyringe</code> you just need a small fix to make everything works, just follows these steps:</p>
<ul>
<li>
<p>Create <code>reflect-metadata-import.ts</code> under <code>src/</code> folder,</p>
<pre><code>// src/reflect-metadata-import.ts

import "reflect-metadata";
</code></pre>
</li>
<li>
<p>Create <code>bunfig.toml</code> file under root folder</p>
<pre><code>// /bunfig.toml

preload = ["./src/reflect-metadata-import.ts"]
</code></pre>
</li>
</ul>
<p>&lt;a name="email-and-password-authentication"&gt;&lt;/a&gt;</p>
<h2>Email and password authentication</h2>
<p>Once you are done with the initial setup, we can now pass to implements the first step, that will be the creation of a basic email and password authentication.</p>
<p>Let's start by creating the controller, as I said in the Architecture Overview the <em>controllers are responsible for routing requests</em>.</p>
<p>Before define the actual controller let's explicit define how a controller is shaped.</p>
<p>Create a <code>interfaces/</code> folder under <code>src</code>, and add the <code>controller.interface.ts</code> file.</p>
<p>This file as expected will contains the shape of all out Controller classes.</p>
<pre><code>// src/interfaces/controller.interface.ts
import { Hono } from "hono";
import type { HonoTypes } from "./../types/hono.type";

import type { BlankSchema } from "hono/types";

export interface Controller {
 controller: Hono&lt;HonoTypes, BlankSchema, "/"&gt;;
 routes(): any;
}
</code></pre>
<p>The <code>HonoTypes</code> is an handy type used to define some global type, let's define it in the <code>src/types/hono.type.ts</code> file.</p>
<pre><code>//src/types/hono.type.ts
import type { Promisify, RateLimitInfo } from "hono-rate-limiter";

export type HonoTypes = {
 Variables: {
  userId: string;
  rateLimit: RateLimitInfo;
  rateLimitStore: {
   getKey?: (key: string) =&gt; Promisify&lt;RateLimitInfo | undefined&gt;;
   resetKey: (key: string) =&gt; Promisify&lt;void&gt;;
  };
 };
};
</code></pre>
<p>Now let's define the Authentication Controller, create a <code>controllers/</code> folder under <code>src/</code> and add <code>auth.controller.ts</code> file.</p>
<p>Here we have to define a controller class that <code>implements</code> the <code>Controller</code> interface. Let's do it.</p>
<pre><code>// src/controllers/auth.controller.ts

import { Hono } from "hono";
import type { HonoTypes } from "./../types/hono.type";
import { injectable } from "tsyringe";
import { Controller } from "../interfaces/controller.interface";

@injectable()
export class AuthController implements Controller {
 controller = new Hono&lt;HonoTypes&gt;();

 constructor() {}

 routes() {
  return this.controller;
 }
}
</code></pre>
<p>This is the shape of our <code>AuthController</code> and it will be the shape of all the other controller that you will implements in your application.</p>
<p>The <code>@injectable</code> keywords is a <strong>decorator</strong> that tells us that this class is a dependency of the project and we can retrive its instance everywhere in the application, because it will be injected at runtime, I link <a href="https://github.com/microsoft/tsyringe?tab=readme-ov-file#injectable">here</a> the official documentation.</p>
<p>Then we will se that we can retrive it by doing:</p>
<pre><code>const instance = container.resolve(AuthController);
</code></pre>
<p>But the question is: where do I have to retrieve it?
Easy, in the <code>index.ts</code> . This file is very important, it is the <strong>entry point</strong> of your application, every thing starts from there.</p>
<p>Most likely, by running</p>
<pre><code>bun create hono@latest
</code></pre>
<p>You will probably get a <code>index.ts</code> like this:</p>
<pre><code>// src/index.ts
import { Hono } from "hono";

const app = new Hono();

app.get("/", (c) =&gt; {
 return c.text("Hello Hono!");
});

export default app;
</code></pre>
<p>We will now edit a bit to reflect our needs.</p>
<pre><code>// src/index.ts
import "reflect-metadata";
import { Hono } from "hono";
import { container } from "tsyringe";
import { AuthController } from "./controllers/auth.controller";

/* ----------------------------------- Api ---------------------------------- */

const app = new Hono().basePath("/api");

/* --------------------------------- Routes --------------------------------- */

const authRoutes = container.resolve(AuthController).routes();

app.route("/auth", authRoutes);

app.get("/", (c) =&gt; {
 return c.text("Hello Hono!");
});

/* -----------------------------------Exports----------------------------------*/

export default app;
</code></pre>
<p>Seems all clear:</p>
<ul>
<li>We add a base path for the application, now all the routes that out app handle are under the <code>/api</code> route.</li>
<li>We "import" our instance of the <code>AuthController</code>.</li>
<li>We define the <code>/auth</code> route, for handling our authentication routes.</li>
<li>We add the <code>import "reflect-metadata";</code> for the <code>tsyringe</code> lib to run on <code>bun</code>.</li>
<li>We can keep the <code>GET</code> endpoint on <code>/</code> for now, just for testing purpose, but it is up to you.</li>
</ul>
<h3>Defining routes</h3>
<p>Now that we have our controller we can just define routes inside of it.</p>
<p>As you can imagine for now we need just <code>login</code> and <code>signup</code>, let's see how can we do it in <code>Hono</code> with our setup.</p>
<pre><code>// src/controllers/auth.controller.ts
import { Hono } from "hono";
import type { HonoTypes } from "./../types/hono.type";
import { inject, injectable } from "tsyringe";
import { Controller } from "../interfaces/controller.interface";
import { zValidator } from "@hono/zod-validator";
import { loginDTO } from "../dtos/login.dto";
import { signUpDTO } from "../dtos/signup.dto";
import { AuthService } from "../services/auth.service";
import { limiter } from "../middlewares/limiter.middleware";

@injectable()
export class AuthController implements Controller {
 controller = new Hono&lt;HonoTypes&gt;();

 constructor(
  @inject(AuthService) private readonly authService: AuthService,
  @inject(RefreshTokenService)
  private readonly refreshTokenService: RefreshTokenService,
  @inject(EmailVerificationsService)
  private readonly emailVerificationsService: EmailVerificationsService,
  @inject(PasswordResetService)
  private readonly passwordResetService: PasswordResetService
 ) {}

 routes() {
  return this.controller
   .post(
    "/login",
    zValidator("json", loginDTO),
    limiter({ limit: 10, minutes: 60 }),
    async (context) =&gt; {
     const body = context.req.valid("json");
     const { user, accessToken, refreshToken } =
      await this.authService.login(body);
     return context.json({ user, accessToken, refreshToken });
    }
   )
   .post(
    "/signup",
    zValidator("json", signUpDTO),
    limiter({ limit: 10, minutes: 60 }),
    async (context) =&gt; {
     const data = context.req.valid("json");
     const newUser = await this.authService.signup(data);
     return context.json(newUser);
    }
   );
 }
}
</code></pre>
<p>Of course we need 2 POST endpoint, and in Hono, you can pass few things as parameter in a route, I will not go in detail of everything since we will see what we need on the fly.</p>
<p>For now you need to know that:</p>
<ul>
<li>The <strong>first</strong> parameter is the <strong>path</strong> of your endpoint,</li>
<li>You can eventually pass a <strong>validator</strong> and/or a <strong>limiter</strong> or whatever <strong>middleware</strong> you want,</li>
<li>lastly you will have your <strong>function</strong> that will be exectued whenever the endpoint get triggered, usually it is asyncronous, for obvious reason.</li>
</ul>
<p>As you can see I keep the response JSON as clean as possibile, to make it easier to deserialize in the frontend, but it is just my preference, you can pick wich standard you most like, in this case I will highly suggest you to make a custom response object, to be as consistent as possible.</p>
<p>There are a lot of stuff beign added in this snippet, so let's try to make some order.</p>
<h4>Zod DTOs Validation</h4>
<p>The <code>zValidator()</code> function comes from the <code>zod-validator</code> hono library, as you can imagine, this function actually takes 2 parameters, a string, that will be used to validate it, and a <code>zod object</code>.</p>
<p>I prefer to keep all the DTOs (Data Transfer Object) in a separate folder. You can create the folder <code>/dtos</code> under <code>/src</code> and create the file <code>login.dto.ts</code> and <code>user.dto.ts</code>.</p>
<p>Data Transfer Objects (DTOs) are used to define the shape of data that is passed. They are used to validate data and ensure that the correct data is being passedto the correct methods.</p>
<p>For the <strong>Login DTO</strong> is all simple, just email and password, so:</p>
<pre><code>// src/dtos/login.dto.ts

import { z } from "zod";

export const loginDTO = z.object({
 email: z
  .string({
   required_error: "email-required",
  })
  .email(),
 password: z
  .string({
   required_error: "password-required",
  })
  .min(8, "password-too-short")
  .max(32, "password-too-long"),
});

export type LoginDTO = z.infer&lt;typeof loginDTO&gt;;
</code></pre>
<p>As you can see in Zod you can also include custom error messages, and custom type of validation, I also infer the type from the zod object, so we can use it also in the service, as object that is passed from the controller, it will be much cleaner in a minute.</p>
<p>Of course in the body of the function I actually validate this object that I recive as a request with:</p>
<pre><code>const data = context.req.valid("json");
</code></pre>
<p>We use <code>"json"</code> as a key, and is the same key we put in the <code>zValidator()</code>. This process ensure us that we will have full <strong>type safety</strong> across the endpoint, and we do not get some data that we don't actually need.</p>
<p>The next step is to do the same for <strong>Sign Up DTO</strong>,</p>
<pre><code>// src/dtos/signup.dto.ts

import { z } from "zod";
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
import { usersTable } from "./../tables";

export const signUpDTO = createInsertSchema(usersTable)
 .extend({
  passwordConfirmation: z.string({
   required_error: "password-confirmation-required",
  }),
  email: z.string().email(),
 })
 .omit({
  id: true,
  createdAt: true,
  updatedAt: true,
 })
 .refine((data) =&gt; data.password === data.passwordConfirmation, {
  message: "passwords-donot-match",
  path: ["passwordConfirmation"],
 });

export type SignUpDTO = z.infer&lt;typeof signUpDTO&gt;;
</code></pre>
<p>So now the "music" is a bit different than before, as you can see we introduce two new things, <code>createInsertSchema</code> and <code>usersTable</code>.</p>
<p>The <code>createInsertSchema()</code> is a function that comes from <code>drizzle-zod</code> a very convenient package to use in combo with Drizzle. It provides some time-saving API that will "translate" your Drizzle Schema into zod object, both for insert and for the selection.</p>
<p>So the <code>createInsertSchema()</code> will take a <strong>Zod Schema</strong> as an argument and will return a <strong>Zod Object</strong>.</p>
<p>For the <code>usersTable</code> we will get there in a minute.</p>
<p>In this case we do also need some other adjustment to the created Zod Object, since we have to <code>extend</code> it with the password confirmation and we of course do not need to insert the <code>id</code>, <code>createdAt</code> and <code>updatedAt</code> when we create a new user from the signup form.</p>
<p>We finally refine the Zod Object by ensuring that the <code>password</code> and <code>passwordConfirmation</code> are the same.</p>
<h4>Users Table</h4>
<p>I talk about zod validation and I mention the <code>usersTable</code> but I actually never declare it, let's do it right now.</p>
<p>As I said early in the article we will store all the <code>Drizzle Schema</code> of the database under the <code>src/infrastructure/database/tables/</code> folder, so create the <code>users.table.ts</code> file under this folder.</p>
<pre><code>// src/infrastructure/database/tables/users.table.ts
import { citext, timestamps } from "./utils";
import { boolean, pgTable, text } from "drizzle-orm/pg-core";
import { createId } from "@paralleldrive/cuid2";

export const usersTable = pgTable("users", {
 id: text("id")
  .primaryKey()
  .$defaultFn(() =&gt; createId()),
 email: citext("email").notNull().unique(),
 password: text("password").notNull(),
 ...timestamps,
});
</code></pre>
<p>This is the structure of the <code>usersTable</code> so far, I will not go in detail of the Drizzle implementation, you can find a good guide on <a href="https://orm.drizzle.team/docs/sql-schema-declaration">their documentation</a>.</p>
<p>Just a quick reminder to create a <code>src/infrastructure/database/tables/index.ts</code> file:</p>
<pre><code>// src/infrastructure/database/tables/index.ts
export * from "./users.table";
</code></pre>
<p>In that way we can reference all the schemas in one in the <code>drizzle.config.ts</code>, we just mention last chapter.</p>
<pre><code>// src/infrastructure/database/index.ts
import { drizzle } from "drizzle-orm/postgres-js";
import postgres from "postgres";
import * as schema from "./tables"; // Add the import here

export const client = postgres(Bun.env.DATABASE_URL ?? "", { max: 10 });
export const db = drizzle(client, { schema });
</code></pre>
<p>There are somethings that we actually did not encounter so far, the <code>createId()</code> function, that is just a function to create reliable <code>id</code> from the <code>paralleldrive</code> library, but also the <code>citext</code> and <code>timestamps</code>.</p>
<p>The <code>citext</code> represent the <strong>case insensitive text</strong> and it is just a <code>customType</code> for Drizzle, and the <code>timestamps</code> as you can imagine are just the <code>createdAt</code> and <code>updatedAt</code> fields "merged together".</p>
<p>You can place both under the <code>src/infrastructure/database/tables/utils.ts</code> file, that you have to create.</p>
<pre><code>// src/infrastructure/database/tables/utils.ts
import { timestamp } from "drizzle-orm/pg-core";
import { customType } from "drizzle-orm/pg-core";

export const citext = customType&lt;{ data: string }&gt;({
 dataType() {
  return "citext";
 },
});

export const timestamps = {
 createdAt: timestamp("created_at", {
  mode: "date",
  withTimezone: true,
 })
  .notNull()
  .defaultNow(),
 updatedAt: timestamp("updated_at", {
  mode: "date",
  withTimezone: true,
 })
  .notNull()
  .defaultNow(),
};
</code></pre>
<p>A very <strong>important</strong> step is to create</p>
<h4>Limiter Middleware</h4>
<p>The limiter middleware comes in handy when you have to ensure that users not spam your endpoints, so you can create a <code>src/middleware/limiter.middleware.ts</code> file.</p>
<pre><code>// src/middleware/limiter.middleware.ts
import { rateLimiter } from "hono-rate-limiter";
import type { HonoTypes } from "./../types/hono.type";

export function limiter({
 limit,
 minutes,
 key = "",
}: {
 limit: number;
 minutes: number;
 key?: string;
}) {
 return rateLimiter({
  windowMs: minutes * 60 * 1000, // every x minutes
  limit, // Limit each IP to 100 requests per `window` (here, per 15 minutes).
  standardHeaders: "draft-6", // draft-6: `RateLimit-*` headers; draft-7: combined `RateLimit` header
  keyGenerator: (c) =&gt; {
   const vars = c.var as HonoTypes["Variables"];
   const clientKey = vars.userId || c.req.header("x-forwarded-for");
   const pathKey = key || c.req.routePath;
   return `${clientKey}_${pathKey}`;
  }, // Method to generate custom identifiers for clients.
 });
}
</code></pre>
<h4>Login and Signup Service</h4>
<p>As you can see I almost cover everything I show you in the <code>AuthController</code> but I didn't mention the most important part, the <code>AuthService</code>.</p>
<p>As I mention before services in general are responsible for handling business logic.</p>
<p>Obviously we will use <code>Dependency Injection</code> also for the <code>Services</code>, the base of the <code>AuthService</code> and in general of the other services too, will be a basic <code>@injectable()</code> class with a bunch of methods:</p>
<pre><code>@injectable()
export class AuthService {
 constructor() {}
}
</code></pre>
<p>Inside of the service a right as we saw before, we'll need only two methods for now, <code>login</code> and <code>signup</code>.</p>
<pre><code>// src/services/auth.service.ts
import { inject, injectable } from "tsyringe";
import { BadRequest, InternalError } from "../common/error";
import { HTTPException } from "hono/http-exception";
import { HashingService } from "./hashing.service";
import { LoginDTO } from "../dtos/login.dto";
import { SignUpDTO } from "../dtos/signup.dto";
import { UsersRepository } from "../repositories/user.repository";

@injectable()
export class AuthService {
 constructor(
  @inject(HashingService) private readonly hashingService: HashingService,
  @inject(UsersRepository) private readonly usersRepository: UsersRepository
 ) {}

 async login(data: LoginDTO) {
  try {
   const user = await this.usersRepository.findOneByEmail(data.email);
   if (!user) {
    throw BadRequest("invalid-email");
   }
   const hashedPassword = await this.hashingService.verify(
    user.password,
    data.password
   );

   if (!hashedPassword) {
    throw BadRequest("wrong-password");
   }

   return user;
  } catch (e) {
   if (e instanceof HTTPException) {
    throw e;
   }
   throw InternalError("error-login");
  }
 }

 async signup(data: SignUpDTO) {
  try {
   const existingEmail = await this.usersRepository.findOneByEmail(
    data.email
   );
   if (existingEmail) {
    throw BadRequest("email-already-in-use");
   }
   const hashedPassword = await this.hashingService.hash(data.password);
   data.password = hashedPassword;

   const newUser = await this.usersRepository.create(data);

   return newUser;
  } catch (e) {
   if (e instanceof HTTPException) {
    throw e;
   }
   throw InternalError("error-signup");
  }
 }
}
</code></pre>
<p>I know I introduced a lot of code, so let's break it down.</p>
<ul>
<li>
<p>Login</p>
<ul>
<li>Check if an user at given email address is extisting, if not we throw error;</li>
<li>Check the password that the user send in the request and the hash of the password stored in the database, be basically hash again the password in the request and check if the two hash are the same, if yes it means it is the correct password, otherwise it is the wrong password.</li>
<li>then return the user.</li>
</ul>
</li>
<li>
<p>Signup</p>
<ul>
<li>Check if email in the request is linked to some user, and exsist in the database;</li>
<li>If exist a user with the email sended in the request, you can't proceed with the sign up since a user with this email already exist, and the email is a unique attribute for the user.</li>
<li>If the email is not associated to any user, proceed with hashing the password in the request, set the hash as the password of the user;</li>
<li>create the new user and return it.</li>
</ul>
</li>
</ul>
<h4>Error Handling</h4>
<p>With the introduction of the service, I of course introduce the error handling part.</p>
<p>As for the response, I want to keep it minimal. So I create some predefined <code>wrappers</code>, so I can easy reference to them in my services:</p>
<pre><code>// src/commons/error.ts
import { StatusCodes } from "./status-codes";
import { HTTPException } from "hono/http-exception";

export function TooManyRequests(message: string = "Too many requests") {
 return new HTTPException(StatusCodes.TOO_MANY_REQUESTS, { message });
}

export function Forbidden(message: string = "Forbidden") {
 return new HTTPException(StatusCodes.FORBIDDEN, { message });
}

export function Unauthorized(message: string = "Unauthorized") {
 return new HTTPException(StatusCodes.UNAUTHORIZED, { message });
}

export function NotFound(message: string = "Not Found") {
 return new HTTPException(StatusCodes.NOT_FOUND, { message });
}

export function BadRequest(message: string = "Bad Request") {
 return new HTTPException(StatusCodes.BAD_REQUEST, { message });
}

export function InternalError(message: string = "Internal Error") {
 return new HTTPException(StatusCodes.INTERNAL_SERVER_ERROR, { message });
}
</code></pre>
<p>As you can see these function wraps the default <code>HTTPException</code> that <code>hono</code> give to us, the <code>StatusCode</code> is an <code>enum</code> that is stored in a separate file, I will not paste it here, since it is a quite big file, but you can find it by yourself <a href="https://github.com/prettymuchbryce/http-status-codes/blob/master/src/status-codes.ts">here</a>, you just need to paste it, and copy in the <code>src/costants/status-codes.ts</code> file.</p>
<h4>Hashing Service</h4>
<p>Before diving into the <code>Repository</code> I will first introduce the <code>Hashing Service</code>, this is a very small service that is responsible to handle, as you can imagine, the hashing part of the application.</p>
<pre><code>// src/services/hashing.service.ts
import { injectable } from "tsyringe";
import { Scrypt } from "oslo/password";

@injectable()
export class HashingService {
 private readonly hasher = new Scrypt();
 // private readonly hasher = new Argon2id(); // argon2id hasher

 async hash(data: string) {
  return this.hasher.hash(data);
 }

 async verify(hash: string, data: string) {
  return this.hasher.verify(hash, data);
 }
}
</code></pre>
<p>I use <code>Scrpt</code> as the hashing algorithm due to its higher compatability and it uses less memory than <code>Argon2id</code>.</p>
<p>You can use <code>Argon2id</code> or any other hashing algorithm you prefer, it will be the same as you can see in the comment line of code.</p>
<h4>User Repository</h4>
<p>As written in the introduction the <code>repository</code> layer is responsible to handle the interaction with the <code>db</code> and he does not know anything about the buisness logic or route handling.</p>
<p>It just write, delete, update and retrive data from the database.</p>
<p>Since <code>DrizzleORM</code> offers also the possibility to perform <code>transaction</code> in <code>PostgreSQL</code> we will define a general shape for a <code>Repository</code>.</p>
<pre><code>// src/interfaces/repository.interface.ts
import type { DatabaseProvider } from "../providers/database.provider";

export interface Repository {
 trxHost(trx: DatabaseProvider): any;
}
</code></pre>
<p>The interface is really simple, but as usual I introduce a new piece of the puzzle.</p>
<h5>Database Provider</h5>
<p>I do not introduced the <code>provider</code> concept so far, so let me explain better.</p>
<p>This is how the <code>DatabaseProvider</code> looks like.</p>
<pre><code>// src/providers/database.provider.ts
import { container } from "tsyringe";
import { db } from "../infrastructure/database";

// Symbol
export const DatabaseProvider = Symbol("DATABASE_TOKEN");

// Type
export type DatabaseProvider = typeof db;

// Register
container.register&lt;DatabaseProvider&gt;(DatabaseProvider, { useValue: db });
</code></pre>
<p>As you can see I'm using the <code>db</code> instance that I previously declared in the infrastructure part. In that way we ensure that we are using the same instance of <code>db</code> across all the application, and we avoid the "error prone" approach of importing manually the <code>db</code> inside each repository.</p>
<p>Indeed in this case <code>tsyringe</code> <em>provides</em> us the same instance of the same object across all the application, thanks to <strong>Dependency Injection</strong>.</p>
<h5>User Repository Implementation</h5>
<p>In this project I will not make a separate distinction between the shape of the repository and the repository implementation it self, you follow this approach if you prefer ,but let's see how the <code>user repository</code> is made up.</p>
<pre><code>// src/repositories/user.repository.ts
import { inject, injectable } from "tsyringe";
import type { Repository } from "../interfaces/repository.interface";
import { eq, type InferInsertModel } from "drizzle-orm";
import { DatabaseProvider } from "../providers/database.provider";
import { usersTable } from "../infrastructure/database/tables";
import { takeFirstOrThrow } from "../infrastructure/database/utils";
import { BadRequest } from "../common/error";

export type CreateUser = InferInsertModel&lt;typeof usersTable&gt;;
export type UpdateUser = Partial&lt;CreateUser&gt;;

@injectable()
export class UsersRepository implements Repository {
 constructor(@inject(DatabaseProvider) private db: DatabaseProvider) {}

 async findAll() {
  return this.db.query.usersTable.findMany();
 }

 async findOneById(id: string) {
  return this.db.query.usersTable.findFirst({
   where: eq(usersTable.id, id),
  });
 }

 async findOneByIdOrThrow(id: string) {
  const user = await this.findOneById(id);
  if (!user) throw BadRequest("user-not-found");
  return user;
 }

 async findOneByEmail(email: string) {
  return this.db.query.usersTable.findFirst({
   where: eq(usersTable.email, email),
  });
 }

 async create(data: CreateUser) {
  return this.db
   .insert(usersTable)
   .values(data)
   .returning()
   .then(takeFirstOrThrow);
 }

 async update(id: string, data: UpdateUser) {
  return this.db
   .update(usersTable)
   .set(data)
   .where(eq(usersTable.id, id))
   .returning()
   .then(takeFirstOrThrow);
 }

 trxHost(trx: DatabaseProvider) {
  return new UsersRepository(trx);
 }
}
</code></pre>
<p>Here we are using a lot of things that we mention in the previous paragraphs, like the <code>takeFirstOrThrow</code> function, the <code>DatabaseProvider</code> the super helpfull <code>InferInsertModel</code> from <code>drizzle-zod</code>, so I will not go in details of these, as I wont go in details of the <code>drizzle</code> query creation, since it really depends on your ORM that of course could possibly be not Drizzle.</p>
<h4>Starting Docker and Testing</h4>
<p>So far we actually implement a very <strong>basic email and password system</strong> we will go in deep with the other features (sessions, refreshToken, email validation, etc...) later on in the article, I really wanna go <strong>step-by-step</strong> so you can fully understand the whole process.</p>
<p>For testing out what you made so far you can use <code>Postman</code> or <code>httpie</code> or what you prefer to test your endpoint.</p>
<p>But first you need to start the whole system.</p>
<ul>
<li>Generate the migration: <code>drizzle-kit generate</code>,</li>
<li>Push the changes: <code>drizzle-kit push</code>,</li>
<li>Start Docker: <code>docker-compose up -d --build</code></li>
</ul>
<p>For the for the sake of simplicity I will just put those script inside my <code>package.json</code>:</p>
<pre><code>"scripts": {
    "db:push": "drizzle-kit push",
    "db:generate": "drizzle-kit generate",
    "db:migrate": "drizzle-kit migrate",
    "db:studio": "drizzle-kit studio --verbose",
    "dev": "bun run --hot src/index.ts",
    "initialize": "bun install &amp;&amp; docker-compose up --no-recreate -d &amp;&amp; bun db:migrate",
    "docker:up": "docker-compose up -d",
    "docker:build": "docker-compose up -d --build"
  },
</code></pre>
<p>I just add some self explanatory scripts.</p>
<p>For spin up for the first time the system, just run:</p>
<pre><code>bun db:generate
</code></pre>
<p>To generate the <code>SQL</code> file for the <strong>migration</strong> and:</p>
<pre><code>bun initialize
</code></pre>
<p>To spin up everything, install dependencies, start docker and do the migration.</p>
<p>Once everything is done correctly you can move on with testing out the endpoints.</p>
<p>The <code>json</code> body of the <code>POST</code> request for the <strong>signup</strong> will be something like that:</p>
<pre><code>{
 "email": "email@example.com",
 "password": `test1234`,
 "passwordConfirmation": "test1234"
}
</code></pre>
<p>And the <code>json</code> body of the <code>POST</code> request for the <strong>login</strong> will be something like that:</p>
<pre><code>{
 "email": "email@example.com",
 "password": `test1234`
}
</code></pre>
<p>The url can vary depends on what you put in the controller, in the base path, your port, ecc..</p>
<p>In my case I just need to query <code>http:</code></p>
<h2>JWT Access and Refresh Token System</h2>
<p>Before deep diving into the implementation of the system, let me explain what a <strong>Refresh Token</strong> system is and how it works.</p>
<h3>What is it?</h3>
<p>In the refresh token system, there are two different tokens <code>refreshToken</code> and <code>accessToken</code>.</p>
<ul>
<li>The <code>accessToken</code> is a <strong>short-live</strong> token (usually from couple of minutes up to few days), it is the token that is in the <code>Authorization</code> field of the <code>http request</code> from the client. This token is being validated each times we put a special <code>middleware</code> in the route (we will see it later on), it is not validated, the server will respond with a <code>401 Unauthorized</code>.</li>
</ul>
<h3>How it works?</h3>
<p>So far it seems like a normal <code>JWT</code> authentication in wich the user ,when the <code>accessToken</code> is expired, logs out even if he use the application and send request every day (very bad UX).</p>
<ul>
<li>In the <code>refreshToken</code> system we ensure that if the user keeps using the application, and keeps sending request to the server it will always get fresh new <code>accessToken</code> when it expires, so we the user will not logs out.</li>
<li>For doing that we actually have the needs of a new token, the <code>refreshToken</code> , this is usually a <strong>long-live</strong> token (usually a month or so), that the client store in a persistent database, cache or shared preferences.</li>
<li>The server does not have to store it, but it can be usefull if you wanna for example logs out a user if something bad happen, or if you wanna log out only certain devices (if you store the device ID), we will not cover this section in this article, but we will still <strong>store in the database</strong> the <code>refreshToken</code>.</li>
<li>This token is responsible to handle the case in wich the user request the access to a protected routes with an expired <code>accessToken</code>, in this case the <code>refreshToken</code> "tells" the server that this user (who own the <code>refreshToken</code>) have the right to <strong>access the resource</strong> even if his <code>accessToken</code>, because his <code>refreshToken</code> is still valid.</li>
<li>The whole process is handled both from the client and the server, the flow is the following.
<ul>
<li>The user request the access to a protected resource with an expired <code>accessToken</code>,</li>
<li>The server respond with a <code>401 Unathorized</code></li>
<li>The client intercept this error from the server, and try to send a <code>POST</code> request to the <code>/refresh-token</code> endpoint in the server, with <strong>his own refresh token</strong> that he's is storing in some memory or disk.</li>
<li>The server recive the <code>POST</code> request within the client <code>refreshToken</code> in the body.</li>
<li>If the <code>refreshToken</code> is still valid, and it is not expired, the server will proceed to generate fresh new <code>accessToken</code> and new <code>refreshToken</code> (and store it in disk) and send it back to the client.</li>
<li>The client, if everything so far goes well, will fetch the response, stores the new <code>accessToken</code> and <code>refreshToken</code> from the server, and retry the previous request, with the updated <code>accessToken</code>, otherwise it will presumably log out the user.</li>
</ul>
</li>
</ul>
<p>As you can see there is a lot of <strong>client-server</strong> communication, and I will cover only the server parts, because the client implementation can be various depends on your platform and technology (web, mobile, etc...).</p>
<h3>Defining Routes</h3>
<p>The first thing we need is to specify the endpoint where the user can send the <code>POST</code> request to ask for a new <code>refresh</code> and <code>accessToken</code>.</p>
<p>We can put in the <code>AuthController</code> since it is part of the domain of the "authentication".</p>
<p>As explained before, the user has to send his stored refresh token (the one in the client) to be able to request a new one. I will not separate the <code>DTO</code> for this route, since it is only a string.</p>
<pre><code>// src/controllers/auth.controlle.ts

import { Hono } from "hono";
import type { HonoTypes } from "../types";
import { injectable } from "tsyringe";
import { zValidator } from "@hono/zod-validator";
import { UserService } from "../services/user.service";
import { AuthService } from "../services/auth.service";
import { RefreshTokenService } from "../services/refresh-token.service";
import { loginDto } from "./../../../dtos/login.dto";
import { limiter } from "../middleware/rate-limiter.middlware";
import { z } from "zod":

@injectable()
export class AuthController implements Controller {

 controller = new Hono&lt;HonoTypes&gt;();

 constructor(){
    @inject(AuthService) private readonly authService: AuthService,
    @inject(RefreshTokenService) private readonly refreshTokenService: RefreshTokenService,
 }

 routes(){
     return this.controller
        // login and signup routes...
        .post(
        "/refresh-token",
        zValidator("json", refreshTokenDTO),
        limiter({ limit: 10, minutes: 60 }),
        async (context) =&gt; {
          const refreshTokenBody = context.req.valid("json");
          const { accessToken, refreshToken } =
            await this.refreshTokenService.refreshToken(
              refreshTokenBody.refreshToken,
            );
          return context.json({ accessToken, refreshToken });
        },
      );
 }
}

</code></pre>
<h3>Refresh Token DTO</h3>
<p>The Refresh Token DTO is straight forward, I wont spend more time on it.</p>
<pre><code>// src/dtos/refresh-token.dto.ts
import { z } from "zod";

export const refreshTokenDTO = z.object({
 refreshToken: z.string(),
});

export type RefreshTokenDTO = z.infer&lt;typeof refreshTokenDTO&gt;;
</code></pre>
<h3>Refresh Token Service</h3>
<p>As for the the other endpoints, we do not want to manage the business logic inside the controller, so we create a separate class for it. Create the <code>refresh-token.service.ts</code> under the <code>service</code> folder.</p>
<pre><code>// src/services/refresh-token.service.ts
import { inject, injectable } from "tsyringe";
import { sign, verify } from "hono/jwt";
import { config } from "../common/config";
import { RefreshTokenRepository } from "../repositories/refresh-token.repository";
import { BadRequest, Unauthorized } from "../common/errors";


@injectable()
export class RefreshTokenService {
  constructor(
    @inject(RefreshTokenRepository) private readonly refreshTokenRepository: RefreshTokenRepository,
  ) {}

  // Update refresh token by generating a new one and invalidating the old one
  async refreshToken(refreshToken: string) {
    const session =
      await this.refreshTokenRepository.getSessionByToken(refreshToken);

    if (!session || session.expiresAt &lt; new Date()) {
      throw BadRequest("invalid-refresh-token");
    }

    const newAccessToken = await this.generateAccessToken(session.userId);
    const newRefreshToken = await this.generateRefreshToken(session.userId);

    await this.refreshTokenRepository.updateRefreshToken(
      session.userId,
      refreshToken,
      newRefreshToken,
      config.jwt.refreshExpiresInDate
    );

    return { refreshToken: newRefreshToken, accessToken: newAccessToken };
  }

  async storeSession(userId: string, refreshToken: string) {
    await this.refreshTokenRepository.storeRefreshToken(
      userId,
      refreshToken,
      config.jwt.refreshExpiresInDate
    );
  }

  async generateRefreshToken(userId: string){
    const payload = {
      sub: userId,
      exp: config.jwt.refreshExpiresIn,
    };
    const refreshToken = await sign(payload, config.jwt.refreshSecret));
    return refreshToken;
  }

  async generateAccessToken(userId: string): Promise&lt;string&gt; {
    const payload = {
      sub: userId,
      exp: config.jwt.accessExpiresIn,
    };
    const accessToken = await sign(payload, config.jwt.accessSecret);
    return accessToken;
  }

  async removeRefreshToken(refreshToken: string){
    await this.refreshTokenRepository.removeRefreshToken(refreshToken);
  }

  async invalidateUserSessions(userId: string) {
    await this.refreshTokenRepository.invalidateAllTokensForUser(userId);
  }
}
</code></pre>
<p>As usual I will break down the code in different steps.</p>
<ul>
<li>
<p><strong>Refresh Token Function</strong></p>
<ul>
<li>The refresh token function is responsible to retrieve, if exist in the database, a session based on the given refresh token in the request.</li>
<li>If it does not exist or it is expired, the function will <code>throw</code> an error.</li>
<li>Otherwise it will generate both <code>accessToken</code> and <code>refreshToken</code> and it wills store them in the database.
<ul>
<li>Both the tokens are generated via the <code>hono/jwt</code> library, that <code>hono</code> provides us.</li>
<li>They are generated based on the configuration parameters.</li>
</ul>
</li>
<li>Finally return both the tokens</li>
</ul>
</li>
<li>
<p><strong>JWT Secrets</strong>
I introduced new secrets that need to be added to the <code>.env</code> file.</p>
</li>
</ul>
<pre><code>JWT_ACCESS_SECRET="your_access_secret"
JWT_REFRESH_SECRET="your_refresh_secret"
</code></pre>
<p>Now the <code>config.type.ts</code> file where there are all the <code>types</code> of the configuration need to be updated too.</p>
<pre><code>// src/types/config.type.ts

export const config = (): Config =&gt; ({
 isProduction: process.env.NODE_ENV === "production",
 api: {
  origin: process.env.ORIGIN ?? "",
 },
 postgres: {
  url: process.env.DATABASE_URL ?? "",
 },
 jwt: {
  accessSecret: process.env.JWT_ACCESS_SECRET || "your_access_secret",
  refreshSecret: process.env.JWT_REFRESH_SECRET || "your_refresh_secret",
  accessExpiresIn: Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 7, // 7 days
  refreshExpiresIn: Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 30, // 30 days
  refreshExpiresInDate: new Date(Date.now() + 60 * 60 * 24 * 30 * 1000), // 30 days
 },
});

// the rest of the configuration ...

interface Config {
 isProduction: boolean;
 api: ApiConfig;
 postgres: PostgresConfig;
 jwt: JwtConfig;
}
interface JwtConfig {
 accessSecret: string;
 refreshSecret: string;
 accessExpiresIn: number;
 refreshExpiresIn: number;
 refreshExpiresInDate: Date;
}
</code></pre>
<p>Now it is up to you to choose the expiration dates of the <code>accessToken</code> and <code>refreshToken</code>, as well as the secrets.</p>
<h3>Refresh Token Repository</h3>
<p>Also this service requires a repository since the sessions are stored in the persistent database as discussed previously.</p>
<pre><code>// src/repositories/refres-token.repository.ts
import { inject, injectable } from "tsyringe";
import { DatabaseProvider } from "../providers";
import { eq } from "drizzle-orm";
import { sessionsTable } from "../tables";
import { and } from "drizzle-orm/expressions";
import { takeFirstOrThrow } from "../infrastructure/database/utils";
import { config } from "../common/config";

@injectable()
export class RefreshTokenRepository {
 constructor(@inject(DatabaseProvider) private db: DatabaseProvider) {}

 async storeRefreshToken(userId: string, token: string, expiresAt: Date) {
  return this.db
   .insert(sessionsTable)
   .values({ userId, token, expiresAt })
   .returning()
   .then(takeFirstOrThrow);
 }

 async removeRefreshToken(token: string) {
  return this.db.delete(sessionsTable).where(eq(sessionsTable.token, token));
 }

 async getSessionByToken(refreshToken: string) {
  return this.db.query.sessionsTable.findFirst({
   where: eq(sessionsTable.token, refreshToken),
  });
 }

 async updateRefreshToken(
  userId: string,
  oldToken: string,
  newToken: string,
  expiresAt: Date
 ) {
  const body = { userId, token: newToken, expiresAt };
  await this.db.transaction(async (trx) =&gt; {
   await trx.delete(sessionsTable).where(eq(sessionsTable.token, oldToken));
   await trx.insert(sessionsTable).values(body);
  });
 }

 async invalidateAllTokensForUser(userId: string) {
  return this.db
   .delete(sessionsTable)
   .where(eq(sessionsTable.userId, userId));
 }
}
</code></pre>
<p>In this service the <code>Database Provider</code> that has been declared in the past is needed since a <code>db transaction</code> is needed. For a reference of what is a transaction I will leave the official definition in the <a href="https://www.postgresql.org/docs/current/tutorial-transactions.html">postgres documentation</a>:</p>
<blockquote>
<p><em>Transactions are a fundamental concept of all database systems. The essential point of a transaction is that it bundles multiple steps into a single, all-or-nothing operation. The intermediate states between the steps are not visible to other concurrent transactions, and if some failure occurs that prevents the transaction from completing, then none of the steps ?affect the database at all.</em></p>
</blockquote>
<h4>Sessions Table</h4>
<p>The session table introduced in the repository contains all the sessions of the users.</p>
<p>It will be located under the <code>src/infrastructure/database/tables/</code> folder:</p>
<pre><code>// src/infrastructure/database/tables/sessions.table.ts
import { cuid2 } from "./utils";
import { usersTable } from "./users.table";
import { pgTable, text, timestamp } from "drizzle-orm/pg-core";
import { relations } from "drizzle-orm";
import { createId } from "@paralleldrive/cuid2";

export const sessionsTable = pgTable("sessions", {
 id: text("id")
  .primaryKey()
  .$defaultFn(() =&gt; createId()),
 token: text("token").notNull(),
 userId: text("user_id")
  .notNull()
  .references(() =&gt; usersTable.id, { onDelete: "cascade" }),
 expiresAt: timestamp("expires_at", {
  withTimezone: true,
  mode: "date",
 }).notNull(),
});

export const sessionRelationships = relations(
 sessionsTable,
 ({ many, one }) =&gt; ({
  users: one(usersTable, {
   fields: [sessionsTable.userId],
   references: [usersTable.id],
  }),
 })
);
</code></pre>
<p>Since we added the relationship in the <code>sessionsTable</code> we have to do the same for the <code>usersTable</code></p>
<pre><code>// src/infrastructure/database/tables/users.table.ts
import { relations } from "drizzle-orm";
import { sessionsTable } from "./sessions.table";
// rest of the imports ...

export const usersTable = ... // table declaration

//rest of the code and table definitions ...

export const usersRelations = relations(usersTable, ({ many, one }) =&gt; ({
  sessions: many(sessionsTable),}));
</code></pre>
<p>[ ⚠️⚠️⚠️ ] Do not forget to generate the migration and push it once you have done with the editing of your schema [ ⚠️⚠️⚠️ ]</p>
<h3>Authentication Middleware</h3>
<p>Once defined the routes, the logic and the database integration of the JWT refresh token system, we need to find a way to actually prevent the access to certain resources.</p>
<p>In <code>hono</code>, and other frameworks too, offers the possibility of defining <code>middleware</code> as we did before for the <code>limiter</code> and <code>zValidator()</code>.</p>
<p>Let's define one for protecting only certain routes.</p>
<pre><code>// src/middleware/auth.middleware.ts
import type { MiddlewareHandler } from "hono";
import { createMiddleware } from "hono/factory";
import { verify } from "hono/jwt";
import { Unauthorized } from "../common/error";
import { config } from "../types/config.type";

export const validateAuthSession: MiddlewareHandler = async (c, next) =&gt; {
 const authHeader = c.req.header("Authorization") ?? "";
 const token = authHeader.startsWith("Bearer ") ? authHeader.slice(7) : null;

 if (!token) {
  c.set("userId", null);
  return next();
 }

 try {
  // Verify the access token
  const payload = await verify(token, config.jwt.accessSecret);
  const userId = payload.sub as string;

  if (!userId) {
   c.set("userId", null);
   return next();
  }

  // Set user id in context
  c.set("userId", userId);
 } catch (error) {
  // If token verification fails, set user to null
  c.set("user", null);
 }

 return next();
};

export const requireAuth: MiddlewareHandler&lt;{
 Variables: {
  userId: string;
 };
}&gt; = createMiddleware(async (c, next) =&gt; {
 const user = c.var.userId;
 if (!user)
  throw Unauthorized("You must be logged in to access this resource");
 return next();
});
</code></pre>
<p>As you can see I come up with 2 different middlewares, this is why I will use the <code>validateAuthSession</code> globally, so at each request, the <code>JWT</code> will be validated. And only where needed the <code>requireAuth</code> middleware is placed next to the route to protect it.</p>
<p>To define a global middleware just add this two lines in the <code>index.ts</code> :</p>
<pre><code>// src/index.ts

import { validateAuthSession } from "./server/api/middleware/auth.middleware";

/* --------------------------- Global Middlewares --------------------------- */

app.use("*", cors({ origin: "*" })); // Allow CORS for all origins
app.use(validateAuthSession);
app.use(logger()); // [OPTIONAL] if you wanna log all the request and response, the import is import { logger } from "hono/logger";
</code></pre>
<p>and if you wanna protect a route, just use the <code>requireAuth</code> middleware on the route:</p>
<pre><code> .post(
        "/protected-resource",
        requireAuth,
        async (context) =&gt; {
          return context.text("Access acquired to the protected resource");
        },
      );
</code></pre>
<p>&lt;a name="update-login-flow"&gt;&lt;/a&gt;</p>
<h3>Update Login Flow</h3>
<p>Since now handle our sessions with <strong>JWT</strong> we need to find a way to send back to the client his <code>accessToken</code> and <code>refreshToken</code> so he can e authenticated and can access all the protected resources.</p>
<p>For doing that we take advantage of the <code>RefreshTokenService</code> previously created, since this is part of the business logic we're gonna handle it in the <code>AuthService</code>.</p>
<pre><code>// src/services/auth.service.ts

// Rest of the imports...
import { RefreshTokenService } from "./refresh-token.service";

@injectable()
export class AuthService {
  constructor(
    @inject(HashingService) private readonly hashingService: HashingService,
    @inject(RefreshTokenService) private readonly refreshTokenService: RefreshTokenService,
    @inject(UsersRepository) private readonly usersRepository: UsersRepository,
  ) {}

  async login(data: LoginDTO) {
    try {
      const user = await this.usersRepository.findOneByEmail(data.email);
      if (!user) {
        throw BadRequest("invalid-email");
      }

      const hashedPassword = await this.hashingService.verify(
        user.password,
        data.password,
      );

      if (!hashedPassword) {
        throw BadRequest("wrong-password");
      }

      //if everything is good, create refresh token and access token
      const accessToken = await this.refreshTokenService.generateAccessToken(
        user.id,
      );
      const refreshToken = await this.refreshTokenService.generateRefreshToken(
        user.id,
      );
      //store the refresh token session in the database
      await this.refreshTokenService.storeSession(user.id, refreshToken);

      return { user, accessToken, refreshToken };
    } catch (e) {
      if (e instanceof HTTPException) {
        throw e;
      }
      throw InternalError("error-login");
    }
  }

// Rest of the code ...
</code></pre>
<p>Now let's reflect the changes in the <code>AuthController</code>.</p>
<pre><code>// src/controllers/auth.controllers.ts

// Rest of the code...
 .post(
        "/login",
        zValidator("json", loginDTO),
        limiter({ limit: 10, minutes: 60 }),
        async (context) =&gt; {
          const body = context.req.valid("json");
          const { user, accessToken, refreshToken } =
            await this.authService.login(body);
          return context.json({ user, accessToken, refreshToken });
        },
      )
// Rest of the code...
</code></pre>
<h3>Testing the endpoints</h3>
<p>Now what you can do is to try is to perform a login as we seen in the last chapter.</p>
<p>You should receive an output like this when you login:</p>
<pre><code>{
 "user": {
  "id": "mdh2e14meythwnvupsbxez2r",
  "email": "test@test.com",
  "password": "5b21310d820a9f0099c6e7fc8eefac3a:28160978a8833f334bd2c92f732b7572c73e5045189cf3b3efc39f45a1bab9b56b4dc23235895b304e46e4bbb6913238f3a79de5ef225d68f399baf76f36f062",
  "createdAt": "2024-10-27T15:31:10.420Z",
  "updatedAt": "2024-10-27T15:31:10.420Z"
 },

 "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJtZGgyZTE0bWV5dGh3bnZ1cHNieGV6MnIiLCJleHAiOjE3MzA3NDA5MzF9.-O2kj5Yf1c-PeAp2oDnlYYQZPmLdEG0b9TCFW_z_Yok",

 "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJtZGgyZTE0bWV5dGh3bnZ1cHNieGV6MnIiLCJleHAiOjE3MzI3MjgxMzF9.8DYcg6-y72tNmt6guYt5ePvoGiR1ZJto3M8J4ogVR14"
}
</code></pre>
<p>Now you can perform a <code>POST</code> request to the <code>.../api/auth/refresh-token</code></p>
<p>According to our implementation the body should look like this.</p>
<pre><code>{
 "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJtZGgyZTE0bWV5dGh3bnZ1cHNieGV6MnIiLCJleHAiOjE3MzI3MjgxMzF9.8DYcg6-y72tNmt6guYt5ePvoGiR1ZJto3M8J4ogVR14"
}
</code></pre>
<p>and you should get something like this</p>
<pre><code>{
 "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJtZGgyZTE0bWV5dGh3bnZ1cHNieGV6MnIiLCJleHAiOjE3MzA3NDA5MzF9.-O2kj5Yf1c-PeAp2oDnlYYQZPmLdEG0b9TCFW_z_Yok",

 "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJtZGgyZTE0bWV5dGh3bnZ1cHNieGV6MnIiLCJleHAiOjE3MzI3MjgxMzF9.8DYcg6-y72tNmt6guYt5ePvoGiR1ZJto3M8J4ogVR14"
}
</code></pre>
<p>Two brand new <code>accessToken</code> and <code>refreshToken</code>.</p>
<p>&lt;a name="email-verification"&gt;&lt;/a&gt;</p>
<h2>Email Verification</h2>
<p>One thing necessary for a <strong>robust</strong> authentication is an email verification system, so the users cannot use incorrect or random email address to gather access at your content.</p>
<p>The general <strong>flow</strong> of an email verification system is the following:</p>
<ul>
<li>Once the user signup he will receive an email containing the instruction to activate his account (so verify his email), the possible ways at this point are more or less two:
<ul>
<li>Verify the user by making it click on a link. In this case the user will basically make a <code>GET</code> os <code>POST</code> request to a particular endpoint with some information in the query to verify himself.</li>
<li>Verify the user by sending him a verification code to enter after the registration in the client.</li>
</ul>
</li>
<li>Those two steps are similar but the final result is the same, the UX (for the client) will change a bit, in terms of server the system is basically identical, you will figure out how to switch between the two by your self.</li>
</ul>
<h3>Defining Routes</h3>
<p>We needs just one route for this purpose, since there will be only one endpoint for the email validation.</p>
<pre><code>// src/controllers/auth.controller.ts

// All the imports...

@injectable()
export class AuthController implements Controller {

 controller = new Hono&lt;HonoTypes&gt;();

 constructor(){
    @inject(AuthService) private readonly authService: AuthService,
    @inject(RefreshTokenService) private readonly refreshTokenService: RefreshTokenService,
    @inject(EmailVerificationsService) private readonly emailVerificationsService: EmailVerificationsService,
 }

 routes(){
     return this.controller
        // login, signup and refresh token routes...
        .get(
        "/verify/:userId/:token",
        limiter({ limit: 10, minutes: 60 }),
        async (context) =&gt; {
          const { userId, token } = context.req.param();
          await this.emailVerificationsService.processEmailVerificationRequest(
            userId,
            token,
          );
    // display or return something to the user
        return context.html(`&lt;h1&gt;Email verified!&lt;/h1&gt;`)
        },
      );
  }
}
</code></pre>
<p>The returning object really depends on your client, I just put a generic title here because in my implementation the user is supposed click on a link and whenever he gets on this web page, a <code>GET</code> request will be made, and he will be validated (if <code>token</code> and <code>userId</code> are valid) .</p>
<h3>Email Verification Service</h3>
<p>The process here is pretty straightforward.</p>
<ul>
<li>Whenever a new user is created (<code>signup</code>) the service will process this request.</li>
<li>It creates a new token, his hash (since we store the hash of the token, not the token itself), and the expiry.</li>
<li>A new record in the <code>emailVerificationsTable</code> is created with the email that request the verification, the <code>userId</code> (the ones created in the signup), the hashed token, and the expiry.</li>
<li>An email is sent to the email that request the verification.</li>
</ul>
<p>That is when a new user is being created, let's see when the user request the actual verification.</p>
<ul>
<li>If a record in the <code>emailVerificaitonsTable</code> with the <code>userId</code> (the one in the param of the request) is found, the hased token is compared with the <code>token</code> in the params.</li>
<li>If everything goes okay, the email verification record will be deleted.</li>
<li>Finally the <code>verified</code> status inside the users record will be updated.</li>
</ul>
<p>Let's implement what I just said.</p>
<pre><code>// src/services/email-verification.service.ts
import { inject, injectable } from "tsyringe";
import { DatabaseProvider } from "../providers/database.provider";
import { HashingService } from "./hashing.service";
import { UsersRepository } from "../repositories/user.repository";
import { TokensService } from "./token.service";
import { MailerService } from "./mailer.service";
import { EmailVerificationsRepository } from "../repositories/email-verifications.repository";
import { BadRequest } from "../common/error";

@injectable()
export class EmailVerificationsService {
 constructor(
  @inject(DatabaseProvider) private readonly db: DatabaseProvider,
  @inject(TokensService) private readonly tokensService: TokensService,
  @inject(MailerService) private readonly mailerService: MailerService,
  @inject(HashingService) private readonly hashingService: HashingService,
  @inject(UsersRepository) private readonly usersRepository: UsersRepository,
  @inject(EmailVerificationsRepository)
  private readonly emailVerificationsRepository: EmailVerificationsRepository
 ) {}

 async dispatchEmailVerificationRequest(
  userId: string,
  requestedEmail: string
 ) {
  // generate a token and expiry
  const { token, expiry, hashedToken } =
   await this.tokensService.generateTokenWithExpiryAndHash({
    number: 15,
    time: 30,
    lifespan: "m",
    type: "STRING",
   });
  const user = await this.usersRepository.findOneByIdOrThrow(userId);

  // create a new email verification record
  await this.emailVerificationsRepository.create({
   requestedEmail,
   userId,
   hashedToken,
   expiresAt: expiry,
  });

  // A confirmation-required email message to the proposed new address, instructing the user to
  // confirm the change and providing a link for unexpected situations
  this.mailerService.sendEmailVerificationToken({
   to: requestedEmail,
   props: {
    link: token,
   },
  });
 }

 async processEmailVerificationRequest(userId: string, token: string) {
  const validRecord = await this.findAndBurnEmailVerificationToken(
   userId,
   token
  );
  if (!validRecord) throw BadRequest("invalid-token");
  await this.usersRepository.update(userId, {
   email: validRecord.requestedEmail,
   verified: true,
  });
 }

 private async findAndBurnEmailVerificationToken(
  userId: string,
  token: string
 ) {
  return this.db.transaction(async (trx: any) =&gt; {
   // find a valid record
   const emailVerificationRecord = await this.emailVerificationsRepository
    .trxHost(trx)
    .findValidRecord(userId);
   if (!emailVerificationRecord) return null;

   // check if the token is valid
   const isValidRecord = await this.hashingService.verify(
    emailVerificationRecord.hashedToken,
    token
   );
   if (!isValidRecord) return null;

   // burn the token if it is valid
   await this.emailVerificationsRepository
    .trxHost(trx)
    .deleteById(emailVerificationRecord.id);
   return emailVerificationRecord;
  });
 }
}
</code></pre>
<p>This service involve the actions of other services, since we need to generate tokens, hash and verify them, we need to send email and so on. So since this two features are most likely required in other part of the application let's split them in separated services.</p>
<h4>Token Service</h4>
<pre><code>// src/services/token.service.ts
import { inject, injectable } from "tsyringe";
import { generateRandomString } from "oslo/crypto";
import { TimeSpan, createDate, type TimeSpanUnit } from "oslo";
import { HashingService } from "./hashing.service";

@injectable()
export class TokensService {
 constructor(
  @inject(HashingService) private readonly hashingService: HashingService
 ) {}

 generateNumberToken(number: number) {
  const alphabet = "1234567890";
  return generateRandomString(number, alphabet);
 }

 generateStringToken(number: number) {
  const alphabet = "23456789ABCDEFGHJKLMNPQRSTUVZ";
  return generateRandomString(number, alphabet);
 }

 generateTokenWithExpiry({
  number,
  time,
  lifespan,
  type,
 }: {
  number: number;
  time: number;
  lifespan: TimeSpanUnit;
  type: "NUMBER" | "STRING";
 }) {
  return {
   token:
    type === "NUMBER"
     ? this.generateNumberToken(number)
     : this.generateStringToken(number),
   expiry: createDate(new TimeSpan(time, lifespan)),
  };
 }

 async generateTokenWithExpiryAndHash({
  number,
  time,
  lifespan,
  type,
 }: {
  number: number;
  time: number;
  lifespan: TimeSpanUnit;
  type: "NUMBER" | "STRING";
 }) {
  const token =
   type === "NUMBER"
    ? this.generateNumberToken(number)
    : this.generateStringToken(number);
  const hashedToken = await this.hashingService.hash(token);
  return {
   token,
   hashedToken,
   expiry: createDate(new TimeSpan(time, lifespan)),
  };
 }
}
</code></pre>
<p>As you can see the <code>token service</code> is pretty straightforward, it relies mainly on the <code>hashing service</code> and it expose <strong>useful API</strong> to generate random and secure token.</p>
<h4>Mailer Service</h4>
<p>The mailer service is responsible to give the possibility to send email using <code>html</code> as template language.</p>
<pre><code>// src/services/mailer.service.ts
import fs from "fs";
import path from "path";
import handlebars from "handlebars";
import { injectable } from "tsyringe";
import nodemailer from "nodemailer";

type SendMail = {
 to: string | string[];
 subject: string;
 html: string;
};

type SendTemplate&lt;T&gt; = {
 to: string | string[];
 props: T;
};

@injectable()
export class MailerService {
 private nodemailer = nodemailer.createTransport({
  host: "smtp.ethereal.email",
  port: 587,
  secure: false, // Use `true` for port 465, `false` for all other ports
  auth: {
   user: "adella.hoppe@ethereal.email",
   pass: "dshNQZYhATsdJ3ENke",
  },
 });

 sendEmailVerificationToken(data: SendTemplate&lt;{ link: string }&gt;) {
  const template = handlebars.compile(this.getTemplate("email-verification"));
  return this.send({
   to: data.to,
   subject: "Email Verification",
   html: template({ link: data.props.link }),
  });
 }

 sendResetPasswordOTP(data: SendTemplate&lt;{ otp: string }&gt;) {
  const template = handlebars.compile(this.getTemplate("reset-password"));
  return this.send({
   to: data.to,
   subject: "Password Reset",
   html: template({ code: data.props.otp }),
  });
 }

 private async send({ to, subject, html }: SendMail) {
  const message = await this.nodemailer.sendMail({
   from: '"Example" &lt;example@ethereal.email&gt;', // sender address
   bcc: to,
   subject, // Subject line
   text: html,
   html,
  });
 }

 private getTemplate(template: string) {
  const __dirname = path.dirname(__filename); // get the name of the directory
  return fs.readFileSync(
   path.join(__dirname, `../infrastructure/email-templates/${template}.hbs`),
   "utf-8"
  );
 }
}
</code></pre>
<h4>Email Templates</h4>
<p>Since this is not the main goal of the guide I will not dive into the email template part, but <a href="https://github.com/fres-sudo/hono-auth/tree/main/src/infrastructure/email-templates/">here</a>
you can find the templates that I have used in the guide.</p>
<p>Those files are <code>.hbs</code> that are basically <strong>Handlebars</strong> file, that is a templating engine, you can find the documentation <a href="https://handlebarsjs.com/guide/">here</a></p>
<blockquote>
<p>Handlebars is a simple <strong>templating language</strong>.
It uses a template and an input object to generate HTML or other text formats. Handlebars templates look like regular text with embedded Handlebars expressions.</p>
</blockquote>
<h3>Email Verifications Repository</h3>
<p>The email verifications</p>
<pre><code>// src/repositories/email-verifications.repository.ts
import { inject, injectable } from "tsyringe";
import { DatabaseProvider } from "../providers";
import { and, eq, gte, lte, type InferInsertModel } from "drizzle-orm";
import type { Repository } from "../interfaces/repository.interface";
import { takeFirst, takeFirstOrThrow } from "../infrastructure/database/utils";
import { emailVerificationsTable } from "./../../../tables";

export type CreateEmailVerification = Pick&lt;
 InferInsertModel&lt;typeof emailVerificationsTable&gt;,
 "requestedEmail" | "hashedToken" | "userId" | "expiresAt"
&gt;;

@injectable()
export class EmailVerificationsRepository implements Repository {
 constructor(
  @inject(DatabaseProvider) private readonly db: DatabaseProvider
 ) {}

 // creates a new email verification record or updates an existing one
 async create(data: CreateEmailVerification) {
  return this.db
   .insert(emailVerificationsTable)
   .values(data)
   .onConflictDoUpdate({
    target: emailVerificationsTable.userId,
    set: data,
   })
   .returning()
   .then(takeFirstOrThrow);
 }

 // finds a valid record by token and userId
 async findValidRecord(userId: string) {
  return this.db
   .select()
   .from(emailVerificationsTable)
   .where(
    and(
     eq(emailVerificationsTable.userId, userId),
     gte(emailVerificationsTable.expiresAt, new Date())
    )
   )
   .then(takeFirst);
 }

 async deleteById(id: string) {
  return this.db
   .delete(emailVerificationsTable)
   .where(eq(emailVerificationsTable.id, id));
 }

 trxHost(trx: DatabaseProvider) {
  return new EmailVerificationsRepository(trx);
 }
}
</code></pre>
<h3>Email Verifications Table</h3>
<p>The Email Verifications table will be used to store all the request of email verifications and also to store the tokens that we need to verify the email along the <code>userId</code> and <code>email</code> that performs the request.</p>
<pre><code>import { createId } from "@paralleldrive/cuid2";
import { pgTable, text, timestamp } from "drizzle-orm/pg-core";
import { relations } from "drizzle-orm";
import { usersTable } from "./users.table";
import { timestamps } from "./utils";

export const emailVerificationsTable = pgTable("email_verifications", {
 id: text("id")
  .primaryKey()
  .$defaultFn(() =&gt; createId()),
 hashedToken: text("hashed_token").notNull(),
 userId: text("user_id")
  .notNull()
  .references(() =&gt; usersTable.id)
  .unique(),
 requestedEmail: text("requested_email").notNull(),
 expiresAt: timestamp("expires_at", {
  mode: "date",
  withTimezone: true,
 }).notNull(),
 ...timestamps,
});

export const emailVerificationsRelations = relations(
 emailVerificationsTable,
 ({ one }) =&gt; ({
   fields: [emailVerificationsTable.userId],
   references: [usersTable.id],
  }),
 })
);
</code></pre>
<h3>Users Table</h3>
<p>Since we are verifying the user email, we have to find a way to mark the user as selected, for this purpose we are gonna need a <code>boolean</code> field in the <code>usersTable</code>.</p>
<pre><code>// ... all the imports
export const usersTable = pgTable("users", {
 id: text("id")
  .primaryKey()
  .$defaultFn(() =&gt; createId()),
 email: citext("email").notNull().unique(),
 password: text("password").notNull(),
 verified: boolean("verified").notNull().default(false), // flag to add
 ...timestamps,
});
// ...the rest of the code
</code></pre>
<p>and also update the relations:</p>
<pre><code>export const usersRelations = relations(usersTable, ({ many, one }) =&gt; ({
 sessions: many(sessionsTable),
 emailVerifications: one(emailVerificationsTable, {
  fields: [usersTable.id],
  references: [emailVerificationsTable.userId],
 }),
}));
</code></pre>
<h2>Forgot password, OTP code verification, Reset password</h2>
<p>In addition to handling user authentication through access and refresh tokens, a robust authentication system must also provide mechanisms for users to recover access to their accounts. This is where the <strong>Forgot Password</strong> and <strong>Password Reset</strong> functionalities come into play. Let’s explore what these features entail and how they operate within the authentication flow.</p>
<h3>What is it?</h3>
<p>The <strong>Forgot Password</strong> and <strong>Password Reset</strong> system allows users to securely reset their passwords in case they forget them. This system typically involves the following steps:</p>
<ul>
<li><strong>Forgot Password Request</strong>: Users initiate the password recovery process by providing their registered email address.</li>
<li><strong>OTP (One-Time Password) Verification</strong>: To ensure the request is legitimate, the system sends a one-time password (OTP) to the user's email, which they must verify.</li>
<li><strong>Password Reset</strong>: Once the OTP is validated, users can set a new password for their account.</li>
</ul>
<p>These steps help maintain the security and integrity of user accounts by ensuring that only the rightful owner can reset the password.</p>
<h3>How it works?</h3>
<p>Implementing a secure password reset mechanism involves coordinated client-server interactions. Here’s an overview of the process:</p>
<ol>
<li>
<p><strong>Initiating Password Reset</strong>:</p>
<ul>
<li>The user navigates to the "Forgot Password" section and submits their registered email address.</li>
<li>The client sends a <code>POST</code> request to the <code>/forgotpassword</code> endpoint with the user's email.</li>
<li>The server generates a unique password reset token, stores a hashed version of it in the database, and sends the token to the user's email via the <code>MailerService</code>.</li>
</ul>
</li>
<li>
<p><strong>Verifying the OTP</strong>:</p>
<ul>
<li>Upon receiving the OTP in their email, the user enters it into the application.</li>
<li>The client sends a <code>POST</code> request to the <code>/verify-token</code> endpoint with the email and OTP.</li>
<li>The server validates the token by checking its existence, ensuring it hasn't expired, and verifying its correctness using the <code>HashingService</code>.</li>
<li>If the token is valid, the server responds with a success status, allowing the user to proceed to reset their password.</li>
</ul>
</li>
<li>
<p><strong>Resetting the Password</strong>: - The user enters a new password and confirms it. - The client sends a <code>POST</code> request to the <code>/resetpassword/:token</code> endpoint, including the new password and the token in the URL. - The server verifies the token again to ensure it's still valid. - Upon successful verification, the server updates the user's password in the database using the <code>HashingService</code> to securely hash the new password. - The server also invalidates any existing user sessions to prevent unauthorized access.</p>
</li>
</ol>
<h3>Defining routes</h3>
<p>As usual we'll put the other routes inside the <code>AuthController</code> since this also those topic are parts of the <em>bigger domain</em> of the authentication.</p>
<pre><code>// src/controllers/auth.controller.ts

// All the imports...

@injectable()
export class AuthController implements Controller {

 controller = new Hono&lt;HonoTypes&gt;();

 constructor(){
    @inject(AuthService) private readonly authService: AuthService,
    @inject(RefreshTokenService) private readonly refreshTokenService: RefreshTokenService,
    @inject(EmailVerificationsService) private readonly emailVerificationsService: EmailVerificationsService,
 }

 routes(){
     return this.controller
        // login, signup, refresh token and email verification routes...
 .post(
  "/forgotpassword",
  zValidator("json", passwordResetEmailDTO),
  limiter({ limit: 10, minutes: 60 }),
  async (context) =&gt; {
   const { email } = context.req.valid("json");
   await this.passwordResetService.createPasswordResetToken({
    email,
   });
   return context.json({ status: "success" });
  }
 )
 .post(
  "/verify-token",
  zValidator("json", passwordResetEmailVerificationDTO),
  limiter({ limit: 10, minutes: 60 }),
  async (context) =&gt; {
   const { email, token } = context.req.valid("json");
   await this.passwordResetService.validateToken(token, email);
   return context.json({ status: "success " });
  }
 )
 .post(
  "/resetpassword/:token",
  zValidator("json", passwordResetDTO),
  limiter({ limit: 10, minutes: 60 }),
  async (context) =&gt; {
   const body = context.req.valid("json");
   const token = context.req.param("token");
   await this.passwordResetService.resetPassword(token, body);
   return context.json({ status: "success" });
  }
 );
  }
}
</code></pre>
<p>The response I choose in this case are pretty basics, you can customize them as you want.</p>
<h4>Password Reset DTO</h4>
<p>This is the definitions of the DTOs for the password reset.</p>
<ul>
<li>For the <code>passwordResetEmailDTO</code> in the body of the request we just need the email that perform the request.</li>
<li>in the <code>passwordResetEmailVerificationDTO</code> we need to pass both the email and the token, in this case the <code>OTP</code> code.</li>
<li>lastly the <code>passwordResetDTO</code>is pretty much identical to the system used in the <code>singUpDTO</code> we just need to add the email.</li>
</ul>
<p>Notice that in this case the client is passing the email at every request, this is due the fact that the server is not caching the email, but you can implement a system to do it if you want to avoid the client to pass the email at every request.</p>
<pre><code>// src/dtos/password-reset.dto.ts

import { InferInsertModel } from "drizzle-orm";
import { z } from "zod";
import { passwordResetTable } from "../infrastructure/database/tables/password-reset.table";

export const passwordResetEmailDTO = z.object({
 email: z.string().email(),
});

export const passwordResetEmailVerificationDTO = z.object({
 email: z.string().email(),
 token: z.string().min(6).max(6),
});

export const passwordResetDTO = z
 .object({
  newPassword: z
   .string({ required_error: "required-password" })
   .min(8, "password-too-short")
   .max(32, "password-too-long"),
  confirmNewPassword: z
   .string({ required_error: "required-confirmation-password" })
   .min(8, "password-too-short")
   .max(32, "password-too-long"),
  email: z.string().email(),
 })
 .refine((data) =&gt; data.newPassword === data.confirmNewPassword, {
  message: "passwords-donot-match",
  path: ["passwordConfirmation"],
 });

export type ResetPasswordEmailDto = z.infer&lt;typeof passwordResetEmailDTO&gt;;
export type ResetEmailVerificationDTO = z.infer&lt;
 typeof passwordResetEmailVerificationDTO
&gt;;
export type ResetPasswordDto = z.infer&lt;typeof passwordResetDTO&gt;;
export type CreatePasswordResetRecord = Pick&lt;
 InferInsertModel&lt;typeof passwordResetTable&gt;,
 "hashedToken" | "email" | "expiresAt"
&gt;;
</code></pre>
<h3>Password Reset Service</h3>
<pre><code>import { inject, injectable } from "tsyringe";
import { MailerService } from "./mailer.service";
import { HTTPException } from "hono/http-exception";
import { isWithinExpirationDate } from "oslo";
import { HashingService } from "./hashing.service";
import { TokensService } from "./token.service";
import { UsersRepository } from "../repositories/user.repository";
import { PasswordResetRepository } from "../repositories/password-reset.repository";
import { BadRequest, InternalError } from "../common/error";
import {
 ResetPasswordDTO,
 ResetPasswordEmailDTO,
} from "../dtos/password-reset.dto";

@injectable()
export class PasswordResetService {
 constructor(
  @inject(HashingService) private readonly hashingService: HashingService,
  @inject(TokensService) private readonly tokensService: TokensService,
  @inject(MailerService) private readonly mailerService: MailerService,
  @inject(UsersRepository) private readonly usersRepository: UsersRepository,
  @inject(PasswordResetRepository)
  private readonly passwordResetRepository: PasswordResetRepository
 ) {}

 async validateToken(token: string, email: string) {
  try {
   const record =
    await this.passwordResetRepository.findValidRecordByEmail(email);

   if (!record || !isWithinExpirationDate(record?.expiresAt)) {
    throw BadRequest("invalid-or-expired-token");
   }

   const isValidToken = await this.hashingService.verify(
    record?.hashedToken,
    token
   );

   if (!isValidToken) {
    throw BadRequest("invalid-or-expired-token");
   }

   return { status: "success" };
  } catch (e) {
   if (e instanceof HTTPException) {
    throw e;
   }
   throw InternalError("error-veryfing-token");
  }
 }

 async resetPassword(token: string, data: ResetPasswordDTO) {
  try {
   const record = await this.passwordResetRepository.findValidRecordByEmail(
    data.email
   );
   if (!record || !isWithinExpirationDate(record?.expiresAt)) {
    throw BadRequest("invalid-or-expired-token");
   }

   const isValidToken = await this.hashingService.verify(
    record?.hashedToken,
    token
   );

   if (!isValidToken) {
    throw BadRequest("invalid-or-expired-token");
   }
   const user = await this.usersRepository.findOneByEmail(data.email);

   if (!user) {
    throw BadRequest("no-user-with-this-email");
   }

   if (data.newPassword !== data.confirmNewPassword) {
    throw BadRequest("password-donot-match");
   }

   await this.passwordResetRepository.deleteById(record.id);

   const hashedPassword = await this.hashingService.hash(data.newPassword);

   await this.usersRepository.update(user.id, {
    password: hashedPassword,
   });
  } catch (e) {
   if (e instanceof HTTPException) {
    throw e;
   }
   throw InternalError("error-resetting-password");
  }
 }

 async createPasswordResetToken(data: ResetPasswordEmailDTO) {
  try {
   // generate a token, expiry and hash
   const { token, expiry, hashedToken } =
    await this.tokensService.generateTokenWithExpiryAndHash({
     number: 6,
     time: 15,
     lifespan: "m",
     type: "NUMBER",
    });
   const user = await this.usersRepository.findOneByEmail(data.email);

   if (!user) {
    throw BadRequest("no-user-with-this-email");
   }
   //if there is an existing record delete it
   await this.findRecordAndDelete(user.id);
   // create a new email verification record
   await this.passwordResetRepository.create({
    email: user.email,
    hashedToken: hashedToken,
    expiresAt: expiry,
   });

   this.mailerService.sendResetPasswordOTP({
    to: user.email,
    props: {
     otp: token,
    },
   });
  } catch (e) {
   if (e instanceof HTTPException) {
    throw e;
   }
   throw InternalError("error-creating-password-reset-token");
  }
 }

 async findRecordAndDelete(email: string) {
  const existingRecord =
   await this.passwordResetRepository.findValidRecordByEmail(email);
  if (existingRecord) {
   await this.passwordResetRepository.deleteById(existingRecord.id);
  }
 }
}
</code></pre>
<h3>Password Reset Repository</h3>
<pre><code>import { inject, injectable } from "tsyringe";
import { and, eq, gte, lte, type InferInsertModel } from "drizzle-orm";
import type { Repository } from "../interfaces/repository.interface";
import { takeFirst, takeFirstOrThrow } from "../infrastructure/database/utils";
import { DatabaseProvider } from "../providers/database.provider";
import { passwordResetTable } from "../infrastructure/database/tables/password-reset.table";
import { CreatePasswordResetRecord } from "../dtos/password-reset.dto";

@injectable()
export class PasswordResetRepository implements Repository {
 constructor(
  @inject(DatabaseProvider) private readonly db: DatabaseProvider
 ) {}

 async create(data: CreatePasswordResetRecord) {
  return this.db
   .insert(passwordResetTable)
   .values(data)
   .onConflictDoUpdate({
    target: passwordResetTable.email,
    set: data,
   })
   .returning()
   .then(takeFirstOrThrow);
 }

 async findValidRecordByEmail(email: string) {
  return this.db
   .select()
   .from(passwordResetTable)
   .where(
    and(
     eq(passwordResetTable.email, email),
     gte(passwordResetTable.expiresAt, new Date())
    )
   )
   .then(takeFirst);
 }

 async deleteById(id: string) {
  return this.db
   .delete(passwordResetTable)
   .where(eq(passwordResetTable.id, id));
 }

 trxHost(trx: DatabaseProvider) {
  return new PasswordResetRepository(trx);
 }
}
</code></pre>
<p>&lt;a name="conclusion"&gt;&lt;/a&gt;</p>
<h2>Conclusion</h2>
<p>Building an authentication system with Hono and Drizzle is an essential step towards securing your web application while ensuring smooth user management. From implementing basic email/password authentication to advanced features like JWT-based authentication and password reset flows, this guide covered the key building blocks required for a robust authentication mechanism.</p>
<p>By following this guide, you’ve learned how to create a secure environment with the following functionalities:</p>
<ul>
<li><strong>User Registration</strong>: Secure sign-up and validation of user data.</li>
<li><strong>Login and Session Management</strong>: Efficient handling of JWT access and refresh tokens.</li>
<li><strong>Password Management</strong>: Secure password storage and recovery options.</li>
<li><strong>Email Verification</strong>: Ensuring that users verify their emails before full access.</li>
<li><strong>Forgot Password</strong>: Giving users an easy way to reset their passwords through OTP-based verification.</li>
</ul>
<p>All of this is achieved with well-defined routes, Zod validation, and database interactions using Drizzle ORM. The integration with Docker ensures a smooth development and production environment.</p>
<p>This architecture provides a clean, scalable solution that can be expanded further as your application grows.</p>
<h3>What do to now?</h3>
<p>Now that you've set up the foundational authentication system, it's time to take the following steps to further enhance your application:</p>
<ol>
<li><strong>Security Features</strong>:</li>
</ol>
<ul>
<li><strong>Two-Factor Authentication (2FA)</strong>:
<ul>
<li><strong>Authy</strong>: A popular app for <strong>TOTP-based 2FA</strong> that you can integrate into your system for an additional security layer.</li>
<li><strong>Duo Security</strong>: A comprehensive 2FA solution for web and mobile apps with enterprise-grade features.</li>
</ul>
</li>
</ul>
<ol>
<li><strong>User Experience</strong>:</li>
</ol>
<ul>
<li><strong>Social Logins</strong>:
<ul>
<li><strong>Auth0</strong>: A popular Identity-as-a-Service (IDaaS) provider that simplifies the integration of multiple social logins (Google, Facebook, GitHub, etc.) with easy-to-use SDKs.</li>
<li><strong>Okta</strong>: A powerful identity provider offering social login, SSO (Single Sign-On), and multi-factor authentication (MFA) with easy integration.</li>
</ul>
</li>
<li><strong>Custom Email Templates</strong>:
<ul>
<li><strong>SendGrid</strong>: A robust email delivery service that offers customizable email templates and APIs to send transactional emails such as verification and password reset emails.</li>
<li><strong>Mailgun</strong>: Provides an API for sending emails with advanced analytics and email template management.</li>
</ul>
</li>
</ul>
<ol>
<li><strong>Testing and Quality Assurance</strong>:</li>
</ol>
<ul>
<li><strong>Test Coverage</strong>:
<ul>
<li><strong>SonarCloud</strong>: A code quality and coverage analysis tool that integrates with your CI/CD pipeline and ensures your authentication system is thoroughly tested.</li>
</ul>
</li>
</ul>
<ol>
<li><strong>Documentation</strong>:</li>
</ol>
<ul>
<li><strong>Swagger / OpenAPI</strong>:
<ul>
<li><strong>SwaggerHub</strong>: A platform for designing, documenting, and testing your REST APIs. It offers a comprehensive interface for documenting your authentication API, and it can generate client libraries for different languages.</li>
<li><strong>Redocly</strong>: Another popular OpenAPI-based API documentation tool with a more modern UI for end-users.</li>
</ul>
</li>
</ul>
<ol>
<li><strong>Monitor and Maintain</strong>:</li>
</ol>
<ul>
<li><strong>Error Monitoring</strong>:
<ul>
<li><strong>Sentry</strong>: Provides <strong>real-time error tracking</strong> and performance monitoring, which can help you track down issues in your authentication routes (like invalid tokens or failed login attempts).</li>
<li><strong>Rollbar</strong>: Another tool for tracking runtime errors and sending notifications for any unhandled exceptions or performance issues.</li>
</ul>
</li>
<li><strong>Logs and Monitoring</strong>:
<ul>
<li><strong>Datadog</strong>: Offers infrastructure monitoring, log management, and application performance monitoring (APM). You can track authentication issues, like slow login responses or downtime.</li>
<li><strong>Loggly</strong>: A logging tool for aggregating, searching, and analyzing logs. It's useful for tracking authentication-related logs, such as failed login attempts or token generation events.</li>
</ul>
</li>
</ul>
<ol>
<li><strong>Scaling</strong>:</li>
</ol>
<ul>
<li><strong>Load Balancers</strong>:
<ul>
<li><strong>AWS Elastic Load Balancing (ELB)</strong>: Automatically distributes incoming application traffic across multiple instances, which helps scale the authentication system as your traffic increases.</li>
<li><strong>Nginx</strong>: Can be used as a reverse proxy server for load balancing to distribute requests evenly across your application servers.</li>
</ul>
</li>
</ul>
<ol>
<li><strong>User Feedback and Monitoring</strong>:</li>
</ol>
<ul>
<li><strong>New Relic</strong>: Provides full-stack observability, including user interaction and API monitoring. It helps you track how users interact with your authentication system and whether there are any bottlenecks.</li>
<li><strong>Hotjar</strong>: Allows you to understand user behavior through heatmaps and session recordings. It helps identify where users are getting stuck during login or registration, making it easier to improve the flow.</li>
</ul>
<ol>
<li><strong>CI/CD Integration</strong>:</li>
</ol>
<ul>
<li><strong>GitHub Actions</strong>: Can be used to automate testing, deployment, and continuous integration for your authentication system.</li>
<li><strong>CircleCI</strong>: Another CI/CD tool that allows you to automate your build, test, and deployment process for your authentication system.</li>
</ul>
<p>By following these next steps, you can ensure your authentication system remains secure, user-friendly, and ready for scaling as your project grows. Keep iterating and improving based on feedback, and your users will have a secure and seamless experience.</p>
<h3>Contributing</h3>
<p>If you think you can add value to the project, please feel free to <a href="https://github.com/fres-sudo/hono-auth/pulls">submit a pull request</a> or <a href="https://github.com/fres-sudo/hono-auth/issues">open a issue</a>.</p>
<h3>Resources</h3>
<p>The reference of the resources used in this guide.</p>
<ul>
<li><strong>Architecture</strong>: <a href="https://github.com/Rykuno/TofuStack">Tofu Stack</a></li>
<li><strong>Framework</strong> <a href="https://hono.dev/">HonoJs</a></li>
<li><strong>ORM</strong>: <a href="https://orm.drizzle.team/">DrizzleORM</a></li>
<li><strong>Database</strong>: <a href="https://www.postgresql.org/docs/">PostgreSQL</a></li>
<li><strong>Authentication Reference</strong> : <a href="https://thecopenhagenbook.com/">The Copenhagen Book</a></li>
</ul>
]]></content>
        <author>
            <name>fres</name>
            <uri>https://fres.space</uri>
        </author>
        <published>2024-12-27T00:00:00.000Z</published>
    </entry>
</feed>