<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: aurelien-alet</title>
    <description>The latest articles on DEV Community by aurelien-alet (@aurelien_alet).</description>
    <link>https://dev.to/aurelien_alet</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F874462%2F48020134-acb0-427a-84a4-bef89fb45e05.png</url>
      <title>DEV Community: aurelien-alet</title>
      <link>https://dev.to/aurelien_alet</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aurelien_alet"/>
    <language>en</language>
    <item>
      <title>Hexagonal Architecture with Angular</title>
      <dc:creator>aurelien-alet</dc:creator>
      <pubDate>Wed, 10 Aug 2022 20:22:00 +0000</pubDate>
      <link>https://dev.to/aurelien_alet/hexagonal-architecture-with-angular-8ll</link>
      <guid>https://dev.to/aurelien_alet/hexagonal-architecture-with-angular-8ll</guid>
      <description>&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;A complete, working example&lt;/li&gt;
&lt;li&gt;Implementation choices&lt;/li&gt;
&lt;li&gt;Hexagonal architecture benefits in Angular&lt;/li&gt;
&lt;li&gt;When to use Hexagonal architecture in Angular&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  1 - Introduction
&lt;/h1&gt;

&lt;p&gt;For a long time, Model View Controller seemed to  be the favorite architecture of software developers. It was used in back-end, as well as in front-end code. But with the growing interest of the community for Domain-Driven Design, this architecture has been challenged by its cousin, the "hexagonal" (or "ports and adapters") architecture.&lt;/p&gt;

&lt;p&gt;As MVC, hexagonal architecture uses the separation principle, but also more abstraction, and domain code is central to its architecture. &lt;br&gt;
&lt;em&gt;If you want more information about hexagonal architecture, here is &lt;a href="https://alistair.cockburn.us/hexagonal-architecture/" rel="noopener noreferrer"&gt;a complete article&lt;/a&gt;, written by its designer, Alister Cockburn.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Currently hexagonal architecture is mostly used in back-end code, and there are poor resources about it in front-end code, especially for Angular.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to adapt hexagonal architecture to Angular ? Would it be beneficial ? If you are also interested in these questions, you should read this article.&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  2 - A complete, working example
&lt;/h1&gt;

&lt;p&gt;All the following explanations will be based on &lt;a href="https://github.com/aurelien-alet/angular-toh-hexagonal" rel="noopener noreferrer"&gt;an exemple app I developed, and made available on Github&lt;/a&gt;. This app is based on &lt;a href="https://angular.io/tutorial" rel="noopener noreferrer"&gt;Angular's tour of heroes&lt;/a&gt;. If you launch the app, the displayed interface is the same as in the Angular tutorial, but there are great differences in the code structure. As a reminder, the principle of this small app is to display a list of heroes and to manage (create, delete, modify) them. The &lt;a href="https://www.npmjs.com/package/angular-in-memory-web-api" rel="noopener noreferrer"&gt;angular-in-memory-web-api module&lt;/a&gt; is used to simulate external API calls.&lt;/p&gt;

&lt;p&gt;This is an overview of this example's architecture:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk2lweiasthqx79srjlb4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk2lweiasthqx79srjlb4.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the associated code organization: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgs1mjrt114vs1yhnk2ys.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgs1mjrt114vs1yhnk2ys.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Domain
&lt;/h2&gt;

&lt;p&gt;In hexagonal architecture, the entire domain related code is isolated. The tour of heroes app has the following purposes: display a list of heroes, display details on a specific hero, and display logs of the actions made by the user. The domain related classes are central to the architecture: &lt;code&gt;HeroesDisplayer&lt;/code&gt;, &lt;code&gt;HeoresDetailDisplayer&lt;/code&gt; and &lt;code&gt;MessagesDisplayer&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ports
&lt;/h2&gt;

&lt;p&gt;As you can imagine, domain related code is not lonely in our heroes app. There is also a user interface related code, corresponding to Angular components, and external APIs calls, corresponding to Angular services. In every hexagonal architecture, domain related code doesn't interact directly with all of this code. Instead, objects called ports are used, and they are implemented by interface classes. This weakens the coupling between the elements of our architecture.&lt;/p&gt;

&lt;p&gt;In our heroes app, &lt;code&gt;HeroesDisplayer&lt;/code&gt; and &lt;code&gt;HeoresDetailDisplayer&lt;/code&gt; need to interact with an external service, which stores heroes related interactions. For this purpose, they will expose an &lt;code&gt;IManageHeroes&lt;/code&gt; port. For each of our domain classes, we want to keep track of every user's interactions. That is why they also have an &lt;code&gt;IManageMessages&lt;/code&gt; port.&lt;/p&gt;

&lt;p&gt;The users realize actual actions in our app through display interfaces. These interfaces can be divided in several categories, according to their purpose. To ensure a faithful comparison with the Angular tour of heroes app, we should have interfaces displaying heroes (a list of heroes and a dashboard), an interface displaying hero details, and an interface displaying messages. Therefore, the related ports should be respectively &lt;code&gt;IDisplayHeroes&lt;/code&gt;, &lt;code&gt;IDisplayHeroDetail&lt;/code&gt; and &lt;code&gt;IDisplayMessages&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adapters
&lt;/h2&gt;

&lt;p&gt;Now that our ports are defined, we have to plug adapters on them. One of the benefits of hexagonal architecture is the ease when switching between adapters. For example, the adapter plugged to &lt;code&gt;IManageHeroes&lt;/code&gt; could be an adapter calling a REST API, and we could replace it easily by an adapter using a GraphQL API. In our case, we want our app to be identical to Google tour of heroes app. So we implement an angular service, &lt;code&gt;HeroAdapterService&lt;/code&gt;, calling an in-memory web API, and another, &lt;code&gt;MessageAdapterService&lt;/code&gt;, storing messages locally.&lt;/p&gt;

&lt;p&gt;The adapters for the three other ports are user interface related adapters. In our app, they will be implemented by Angular components. As you can see, the &lt;code&gt;IDisplayHeroes&lt;/code&gt; port is implemented by three adapters. Details will be available in the following.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;As explained above, there is an asymmetry in our adapters, due to their nature. The architecture diagram represents it in the following way: architecture left-side adapters are designed for users interactions, whereas right-side adapters are designed for external services interactions.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  3 - Implementation choices
&lt;/h1&gt;

&lt;p&gt;Because hexagonal architecture was designed for back-end applications, some arrangements have been made in code implementation. These choices are explained in the following part. &lt;/p&gt;

&lt;h2&gt;
  
  
  Angular related objects in domain code
&lt;/h2&gt;

&lt;p&gt;A good practice in hexagonal architecture is to keep domain related code independent of any framework, in order to ensure it is functional for any kind of adapter. But in our code, the domain is highly dependent on Angular and rxjs objects. In fact, we can assume that we won't use several typescript or JavaScript frameworks, in order to keep interface coherence. Also, the angular dependency injection system is very useful to achieve the inversion of control principle. However, it should be possible to use JavaScript promises instead of rxjs observables, but we would have to write a lot of &lt;em&gt;boilerplate&lt;/em&gt; code in our classes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Observable return type in left-side ports
&lt;/h2&gt;

&lt;p&gt;Since the logic behind the code is handled in the domain, one could wonder why returning Observable objects in &lt;code&gt;IDisplayHeroDetail&lt;/code&gt;, &lt;code&gt;IDisplayHeroes&lt;/code&gt; and &lt;code&gt;IDisplayMessages&lt;/code&gt; ports. Indeed, each object returned by the services is handled inside the domain code using &lt;code&gt;pipe&lt;/code&gt; and &lt;code&gt;tap&lt;/code&gt; methods. For example, the hero detail save result returned by &lt;code&gt;HeroAdapterService&lt;/code&gt; is managed directly in the &lt;code&gt;HeroDetailDisplayer&lt;/code&gt;: &lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;&lt;code&gt;hero-detail-displayer.ts&lt;/code&gt;&lt;/strong&gt;
&lt;/h4&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="nf"&gt;askHeroNameChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newHeroName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[...]&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updatedHero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;newHeroName&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_heroesManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;updateHero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;updatedHero&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nf"&gt;tap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_messagesManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`updated hero id=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hero&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
        &lt;span class="nf"&gt;catchError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_errorHandler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleError&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`updateHero id=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hero&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
        &lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hero&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hero&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;hero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}})&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Still, returning an empty observable from the &lt;code&gt;askHeroNameChange&lt;/code&gt; method is interesting if we aim at enabling the interface adapters to know when the data is loaded. For example, when the hero detail changes are effective, we can go back to the previous page: &lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;&lt;code&gt;hero-detail.component.ts&lt;/code&gt;&lt;/strong&gt;
&lt;/h4&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="nf"&gt;changeName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heroDetailDisplayer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;askHeroNameChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newName&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nf"&gt;finalize&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;goBack&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The drawback of this implementation choice is the need of subscribing to each domain function call inside left-side adapters:&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;&lt;code&gt;heroes.component.ts&lt;/code&gt;&lt;/strong&gt;
&lt;/h4&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heroesDisplayer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;askHeroesList&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  HeroesDisplayer class instantiated twice
&lt;/h2&gt;

&lt;p&gt;In our app, dependency injection is handled in &lt;strong&gt;&lt;code&gt;app.module.ts&lt;/code&gt;&lt;/strong&gt;. We use injection tokens to make domain classes accessible inside Angular components. For instance the injection of IDisplayHeroDetail into the HeroDetail component is done this way:&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;&lt;code&gt;app.module.ts&lt;/code&gt;&lt;/strong&gt;
&lt;/h4&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;HeroDetailDisplayer&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../domain/hero-detail-displayer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nl"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;[...]&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;provide&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;IDisplayHeroDetail&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HeroDetailDisplayer&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;[...]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Sets HeroesDetailDisplayer instance as a IDisplayHeroDetail implementation&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;&lt;code&gt;hero-detail.component.ts&lt;/code&gt;&lt;/strong&gt;
&lt;/h4&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;IDisplayHeroDetail&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/app/domain/ports/i-display-hero-detail&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HeroDetailComponent&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;IDisplayHeroDetail&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;heroDetailDisplayer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IDisplayHeroDetail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;[...]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Injects HeroDetailDisplayer inside HeroDetailComponent&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;However, there is a subtlety somewhere in the code: two different injection tokens are generated for the HeroesDisplayer class. Moreover, &lt;code&gt;HeroesComponent&lt;/code&gt; and &lt;code&gt;DashboardComponent&lt;/code&gt; share the same injection token, whereas &lt;code&gt;HeroSearchComponent&lt;/code&gt; component uses another token.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;&lt;code&gt;app.module.ts&lt;/code&gt;&lt;/strong&gt;
&lt;/h4&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;HeroesDisplayer&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../domain/heroes-displayer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nl"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;// Used in HeroesComponent and in DashboardComponent &lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;provide&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;IDisplayHeroes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;useClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HeroesDisplayer&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="c1"&gt;// Used in HeroSearchComponent&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;provide&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;IDisplayHeroesSearch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;useClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HeroesDisplayer&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is because &lt;code&gt;HeroesComponent&lt;/code&gt; and &lt;code&gt;DashboardComponent&lt;/code&gt; can share the same instance of &lt;code&gt;HeroesDisplayer&lt;/code&gt;: they display the same list of heroes. On the other hand, if &lt;code&gt;HeroSearchComponent&lt;/code&gt; had this same instance, each search would affect the displayed heroes, since the &lt;code&gt;heroes&lt;/code&gt; attribute is modified by the &lt;code&gt;askHeroesFiltered&lt;/code&gt; method in &lt;code&gt;HeroesDisplayer&lt;/code&gt;. Sharing the same token for the three components would change our app's behavior:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdjmk2bl9j93bava88cme.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdjmk2bl9j93bava88cme.gif" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  4 - Hexagonal architecture benefits in Angular
&lt;/h1&gt;

&lt;p&gt;The main essence of hexagonal architecture consists in having interchangeable adapters allowing our app to be driven equally by a human, a system, or by tests. In our app, we are highly tied to the Angular framework, which means we do not make a whole benefit from this architecture asset. However, I found some promising insights from experiencing it in front-end code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Decoupled presentational layer, core layer and external services calls
&lt;/h2&gt;

&lt;p&gt;Domain code, corresponding to our core layer, is clearly separated from the interface adapter, namely the presentational layer, by ports. Thanks to these same ports, the risk of adding unwanted code into external service calls is reduced. All the core logic is handled into domain classes.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;&lt;code&gt;heroes.component.ts&lt;/code&gt;&lt;/strong&gt;
&lt;/h4&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;IDisplayHeroes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;heroesDisplayer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IDisplayHeroes&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Imports domain class, corresponding to code layer&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;&lt;code&gt;heroes.component.html&lt;/code&gt;&lt;/strong&gt;
&lt;/h4&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;*ngFor=&lt;/span&gt;&lt;span class="s"&gt;"let hero of heroesDisplayer.heroes"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    [...]
&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Uses heroes information handled by domain code inside view, corresponding to presentational layer&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code factorization
&lt;/h2&gt;

&lt;p&gt;If you look at the original tour of heroes application, the main purpose of the &lt;code&gt;HeroesComponent&lt;/code&gt;, of the &lt;code&gt;HeroSearchComponent&lt;/code&gt; and of the &lt;code&gt;DashboardComponent&lt;/code&gt; are very close. They all display the list of heroes, but the possible interactions differ depending on components. Therefore the related core code, mapping services returns to displayed information, should be factorized. In our code, the domain related code for the three components is factorized: we take advantage of hexagonal port re-usability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;Sometimes, Angular tests can be very painful, even more if core code is mixed with presentational code inside components. This code grows as your application evolves. Keeping our display components, our domain code, and our services isolated from each other make the tests more straightforward. You can easily mock other layers, and focus on testing the current class.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;&lt;code&gt;hero-detail.component.spec.ts&lt;/code&gt;&lt;/strong&gt;
&lt;/h4&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="nf"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;spyIDisplayHeroDetail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jasmine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createSpyObj&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;IDisplayHeroDetail&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;askHeroDetail&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;askHeroNameChange&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;hero&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;spyIDisplayHeroDetail&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;askHeroDetail&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;and&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;returnValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="nx"&gt;spyIDisplayHeroDetail&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;askHeroNameChange&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;and&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;returnValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;[...]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Hero details display tests: domain class and methods can be mocked easily&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  5 - When to use Hexagonal architecture in Angular
&lt;/h1&gt;

&lt;p&gt;Even if we can't totally compare it with back-end code, hexagonal architecture can have some great benefits in some front-end applications. Some use cases seem particularly adapted to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Profile based apps
&lt;/h2&gt;

&lt;p&gt;As we isolated the presentational layer, apps where the same logic is used inside different interfaces, like profile based apps, are good candidates for our architecture. The &lt;a href="https://github.com/aurelien-alet/angular-toh-hexagonal/tree/admin-panel" rel="noopener noreferrer"&gt;admin-panel&lt;/a&gt; branch gives an example of what the app would look like if we added an admin panel interface. This interface, designed for admin users, allows them to do every administrative action inside a single view: adding, changing, deleting or searching for heroes. Only the &lt;code&gt;AdminPanelComponent&lt;/code&gt; is added to the heroes app, no changes inside domain code or services, showing their reusable attribute.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;To launch the administrator interface, run &lt;code&gt;npm run start:admin&lt;/code&gt; on &lt;code&gt;admin-panel&lt;/code&gt; branch.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Apps calling multiple external services
&lt;/h2&gt;

&lt;p&gt;Angular hexagonal architecture is also adapted if you have to contact several external services serving the same purpose. Once again, domain code re-usability simplifies. Let's say we want to call an online service instead of our in-memory heroes service: &lt;a href="https://akabab.github.io/superhero-api/" rel="noopener noreferrer"&gt;the superhero api&lt;/a&gt; by Yoann Cribier. Adding a &lt;code&gt;SuperheroApiAdapterService&lt;/code&gt; is the only thing required, as you can see in the &lt;a href="https://github.com/aurelien-alet/angular-toh-hexagonal/tree/superhero-api" rel="noopener noreferrer"&gt;superhero-api&lt;/a&gt; branch.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;To make the app communicate with superhero-api, run &lt;code&gt;npm run start:superhero-api&lt;/code&gt; on the &lt;code&gt;superhero-api&lt;/code&gt; branch. Observation: in our example, heroes modifying and deletion aren't implemented by the online service.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  6 - Conclusion
&lt;/h1&gt;

&lt;p&gt;This tiny app shows it's possible to adapt hexagonal architecture to an Angular app. Some problems, which haven't been raised by the tour of heroes tutorial app, can be solved using it. &lt;/p&gt;

&lt;p&gt;Thank you for reading !&lt;br&gt;
I hope you enjoyed this article, and I'm very interested in any feedback of this architecture adoption.   &lt;/p&gt;

&lt;p&gt;I also would like to thank Leila for correcting this article.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>angular</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
