<?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: Daniel Berki</title>
    <description>The latest articles on DEV Community by Daniel Berki (@berkid89).</description>
    <link>https://dev.to/berkid89</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%2F52342%2Fbf40e4df-b314-40dc-bf86-3fcc917cad56.png</url>
      <title>DEV Community: Daniel Berki</title>
      <link>https://dev.to/berkid89</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/berkid89"/>
    <language>en</language>
    <item>
      <title>Implement content enricher pattern easily with Message Silo</title>
      <dc:creator>Daniel Berki</dc:creator>
      <pubDate>Fri, 02 Jun 2023 08:55:10 +0000</pubDate>
      <link>https://dev.to/berkid89/implement-content-enricher-pattern-easily-with-message-silo-3jo2</link>
      <guid>https://dev.to/berkid89/implement-content-enricher-pattern-easily-with-message-silo-3jo2</guid>
      <description>&lt;h2&gt;
  
  
  About the pattern
&lt;/h2&gt;

&lt;p&gt;When sending messages from one system to another it is common for the target system to require more information than the source system can provide.&lt;br&gt;
With &lt;strong&gt;content enricher pattern&lt;/strong&gt; you can add an enricher in the middle to pick up messages/events and enrich them before sending downstream to consumers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In this article, we will see how the above pattern can be implemented in the simplest way, without any extra infrastructure!&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  What is Message Silo?
&lt;/h2&gt;

&lt;p&gt;Message Silo is an open-source platform/tool for Developers to auto-correct dead-lettered messages and make integration simpler for event-driven systems.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.message-silo.dev/" rel="noopener noreferrer"&gt;Website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/MessageSilo/MessageSilo" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also has a CLI called &lt;code&gt;siloctl&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  The example case
&lt;/h2&gt;

&lt;p&gt;Suppose we have a service that can send &lt;code&gt;latitude&lt;/code&gt; and &lt;code&gt;longitude&lt;/code&gt; coordinates in a message to a message queue (e.g.: &lt;strong&gt;AWS SQS&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;However, we on the consumer side would need more than this, our application would like to display the name of the country belonging to the coordinate, the city, zip code and other information.&lt;/p&gt;

&lt;p&gt;The message must therefore be enriched. For this we can use some kind of &lt;code&gt;reverse geocode API&lt;/code&gt; (e.g.: &lt;a href="https://geocode.maps.co" rel="noopener noreferrer"&gt;https://geocode.maps.co&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The flow looks something like this:&lt;/strong&gt;&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%2F4i0i3cl1jcdwzlyzkyip.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%2F4i0i3cl1jcdwzlyzkyip.png" alt="Flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In the &lt;code&gt;Enrichment Phase&lt;/code&gt; we will call the external API to get the extra data &amp;amp; transform the message to fit into the consumer expectations.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Let's do it!
&lt;/h2&gt;

&lt;p&gt;Let's see how this all looks in Message Silo!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1.&lt;/strong&gt; Define the YAML file(s)&lt;/p&gt;

&lt;p&gt;Based on the Message Silo &lt;a href="https://github.com/MessageSilo/MessageSilo/wiki/02.-Entities-&amp;amp;-Concepts" rel="noopener noreferrer"&gt;Docs&lt;/a&gt; I created a YAML file that can correlate with our workflow:&lt;/p&gt;

&lt;p&gt;example.yaml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Connection&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;input&lt;/span&gt;
&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS_SQS&lt;/span&gt;
&lt;span class="na"&gt;queueName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test-q-input&lt;/span&gt;
&lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;eu-north-1&lt;/span&gt;
&lt;span class="na"&gt;accessKey&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;XXXXX&lt;/span&gt;
&lt;span class="na"&gt;secretAccessKey&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;XXXXX&lt;/span&gt;
&lt;span class="na"&gt;receiveMode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ReceiveAndDelete&lt;/span&gt;
&lt;span class="na"&gt;enrichers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;reverseGeocoding&lt;/span&gt;
 &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;messageTransformator&lt;/span&gt;
&lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;output&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Enricher&lt;/span&gt;
&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;API&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;reverseGeocoding&lt;/span&gt;
&lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GET&lt;/span&gt;
&lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://geocode.maps.co/reverse?lat={latitude}&amp;amp;lon={longitude}"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Enricher&lt;/span&gt;
&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Inline&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;messageTransformator&lt;/span&gt;
&lt;span class="na"&gt;function&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(x)&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;return&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;latitude:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;x.lat,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;longitude:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;x.lon,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;name:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;x.display_name,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;address:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;x.address&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;};&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Target&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;output&lt;/span&gt;
&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;API&lt;/span&gt;
&lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://myapi.mydomain.com/location/add"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2.&lt;/strong&gt; Apply our solution&lt;/p&gt;

&lt;p&gt;I downloaded the &lt;a href="https://github.com/MessageSilo/MessageSilo/wiki/01.-Getting-Started" rel="noopener noreferrer"&gt;siloctl&lt;/a&gt; and created my account, so I can apply my changes with a single command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;siloctl apply &lt;span class="nt"&gt;-f&lt;/span&gt; c:/temp/example.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3.&lt;/strong&gt; Enjoy! :)&lt;/p&gt;

&lt;p&gt;The established Message Silo connection monitors the messages coming to &lt;code&gt;test-q-input&lt;/code&gt; AWS SQS and automatically transforms the messages with the help of Enrichers (in 2 steps: &lt;code&gt;reverseGeocoding&lt;/code&gt;, &lt;code&gt;messageTransformator&lt;/code&gt;) and then forwards them to the specified API endpoint (&lt;code&gt;output&lt;/code&gt; Target).&lt;/p&gt;

&lt;p&gt;So what we did is we wrote our workflow in a Message Silo configuration:&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%2Ffgvzfca6b9segc60apri.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%2Ffgvzfca6b9segc60apri.png" alt="Message Silo Flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What were the benefits of using Message Silo?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;We didn't have to touch our existing code&lt;/li&gt;
&lt;li&gt;No additional infrastructure elements had to be installed&lt;/li&gt;
&lt;li&gt;We didn't have to write and host the enrichment phase&lt;/li&gt;
&lt;li&gt;Our system elements are remains decoupled&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.enterpriseintegrationpatterns.com/patterns/messaging/DataEnricher.html" rel="noopener noreferrer"&gt;Content Enricher Enterprise Integration Pattern&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://serverlessland.com/event-driven-architecture/visuals/content-enricher-pattern" rel="noopener noreferrer"&gt;Serverless Land&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>opensource</category>
      <category>eventdriven</category>
      <category>tooling</category>
      <category>microservices</category>
    </item>
  </channel>
</rss>
