<?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: Tamimi</title>
    <description>The latest articles on DEV Community by Tamimi (@tweettamimi).</description>
    <link>https://dev.to/tweettamimi</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%2F96312%2F314fd288-cfa8-4661-9372-3806a7eb756f.png</url>
      <title>DEV Community: Tamimi</title>
      <link>https://dev.to/tweettamimi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tweettamimi"/>
    <language>en</language>
    <item>
      <title>Golang and Event-Driven Architecture</title>
      <dc:creator>Tamimi</dc:creator>
      <pubDate>Wed, 06 Apr 2022 18:15:58 +0000</pubDate>
      <link>https://dev.to/tweettamimi/golang-and-event-driven-architecture-5fph</link>
      <guid>https://dev.to/tweettamimi/golang-and-event-driven-architecture-5fph</guid>
      <description>&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%2Fus.v-cdn.net%2F6031588%2Fuploads%2FPAQRBSQ510P9%2Fgopher-2bsolly-2bsky.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%2Fus.v-cdn.net%2F6031588%2Fuploads%2FPAQRBSQ510P9%2Fgopher-2bsolly-2bsky.png" alt="Solace Gopher Solly"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On March 31 2022, I gave a talk at Conf42:Golang about using Go in an event-driven architecture entitled "Gopher in an Event Driven Playground". You can check out the talk here or read along to know more about event-driven systems and how different messaging protocols are used in Go!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/XBkBpFYAHiw?start=76"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  What's all the hype about?
&lt;/h2&gt;

&lt;p&gt;For all of us Go enthusiasts out there, we truly understand the beauty of using Go in applications and microservices because of its lightweight, high performance, and elegant syntax, to name just a few (let the debate start! 🔥).&lt;/p&gt;

&lt;p&gt;So imagine using your favourite programming language (yes, that is Go) with your favourite architecture (yes, that event-driven architecture) - where do you start? Carry on and read further to explore. &lt;/p&gt;

&lt;h3&gt;
  
  
  Hold on, what is an event-driven architecture (EDA)?
&lt;/h3&gt;

&lt;p&gt;Glad you asked! There are loads of resources online that talk about EDA. At its core, an event-driven architecture involves asynchronous communication between applications via publishing and subscribing to events over an &lt;a href="https://solace.com/what-is-an-event-broker" rel="noopener noreferrer"&gt;event broker&lt;/a&gt; using a messaging protocol. &lt;/p&gt;

&lt;p&gt;Some examples of messaging protocols include open standard and open source protocols such as &lt;a href="https://mqtt.org/" rel="noopener noreferrer"&gt;MQTT&lt;/a&gt;, &lt;a href="https://www.amqp.org/" rel="noopener noreferrer"&gt;AMQP&lt;/a&gt;, and &lt;a href="https://www.oracle.com/technical-resources/articles/java/intro-java-message-service.html" rel="noopener noreferrer"&gt;JMS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To delve more into event-driven architecture and explore different use-cases, check out this page on &lt;a href="https://solace.com/what-is-event-driven-architecture" rel="noopener noreferrer"&gt;What is Event-Driven Architecture&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I also wrote a blog post talking about how I built an event-driven NodeJS app on real-time COVID-19 data streams, highlighting the advantages of event-driven architecture, if you want to explore it further:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/solacedevs" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__org__pic"&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%2Forganization%2Fprofile_image%2F636%2F00a14c98-07f3-4270-a819-6221365bd3fa.png" alt="Solace Developers"&gt;
      &lt;div class="ltag__link__user__pic"&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%2Fuser%2Fprofile_image%2F96312%2F314fd288-cfa8-4661-9372-3806a7eb756f.png" alt=""&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/solacedevs/how-i-built-an-event-driven-nodejs-app-on-realtime-covid-19-data-streams-3i98" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;How I built an event-driven NodeJS app on realtime COVID-19 data streams&lt;/h2&gt;
      &lt;h3&gt;Tamimi for Solace Developers ・ Apr 23 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#covid19&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#opensource&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#node&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  fmt.Println("Show me the CODE!")
&lt;/h2&gt;

&lt;p&gt;Alright, we did a high level overview on what EDA is but let's get to business with some hands-on code. Let me show you how to use:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Paho MQTT library for Golang&lt;/li&gt;
&lt;li&gt;The PubSub+ Messaging API for Go&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that all the source code can be found in this open source Github repo:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&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%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/TamimiGitHub" rel="noopener noreferrer"&gt;
        TamimiGitHub
      &lt;/a&gt; / &lt;a href="https://github.com/TamimiGitHub/conf42-golang-eda" rel="noopener noreferrer"&gt;
        conf42-golang-eda
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Conf42 Golang 2022: Gopher in an Event-Driven Playground&lt;/h1&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Talk&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Talk found on YouTube here &lt;a href="https://www.youtube.com/watch?v=XBkBpFYAHiw&amp;amp;feature=youtu.be" rel="nofollow noopener noreferrer"&gt;https://www.youtube.com/watch?v=XBkBpFYAHiw&amp;amp;feature=youtu.be&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Source Code&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;This repo contains source code to showcase how to use the&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Paho MQTT library to publish and subscribe to&lt;/li&gt;
&lt;li&gt;Solace PubSub+ Messaging API for Go to publish messages&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How to run&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;go run solace_publisher.go&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;go run paho_mqtt.go&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note: Update the hostname, username, password, and vpn name to your broker's details&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Extra Resources&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/SolaceSamples/solace-samples-go" rel="noopener noreferrer"&gt;Solace PubSub+ Messaging API for Go samples&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/TamimiGitHub/conf42-golang-eda" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h3&gt;
  
  
  Hands-on 👩‍💻🧑‍💻
&lt;/h3&gt;

&lt;p&gt;Let's start with creating a new directory and initializing go mod. In a new terminal window, execute the following commands:&lt;/p&gt;

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

&lt;span class="n"&gt;mkdir&lt;/span&gt; &lt;span class="n"&gt;funWithEDA&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;cd&lt;/span&gt; &lt;span class="s"&gt;"$_"&lt;/span&gt;
&lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="n"&gt;GoEDA&lt;/span&gt;


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  MQTT
&lt;/h3&gt;

&lt;p&gt;As per definition: "MQTT is an OASIS standard messaging protocol for the Internet of Things (IoT). It is designed as an extremely lightweight publish/subscribe messaging transport that is ideal for connecting remote devices with a small code footprint and minimal network bandwidth"&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.eclipse.org/paho/" rel="noopener noreferrer"&gt;Eclipse Paho&lt;/a&gt; project provides open source, mainly client side, implementations of MQTT in a variety of programming languages. For today's fun coding session, we will be using the &lt;a href="https://pkg.go.dev/github.com/eclipse/paho.mqtt.golang#section-readme" rel="noopener noreferrer"&gt;Eclipse Paho MQTT Go client&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Install the Paho MQTT Go library&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

go get github.com/eclipse/paho.mqtt.golang


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

&lt;/div&gt;
&lt;p&gt;Create a new file and open it with your favourite IDE. I named my file &lt;code&gt;go_mqtt.go&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Initialize the file and import the necessary libraries&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;

&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;

    &lt;span class="n"&gt;mqtt&lt;/span&gt; &lt;span class="s"&gt;"github.com/eclipse/paho.mqtt.golang"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;In your &lt;code&gt;main()&lt;/code&gt; function, start with &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Creating a new MQTT client and configure it&lt;/li&gt;
&lt;li&gt;Add callback functions for

&lt;ol&gt;
&lt;li&gt;Received Messages &lt;/li&gt;
&lt;li&gt;Successful broker connection&lt;/li&gt;
&lt;li&gt;Lost broker connection&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Subscribe to a topic&lt;/li&gt;
&lt;li&gt;Publish on a topic&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;broker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"public.messaging.solace.cloud"&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1883&lt;/span&gt;
    &lt;span class="n"&gt;opts&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;mqtt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewClientOptions&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddBroker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tcp://%s:%d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;broker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"conf42"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetPassword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetDefaultPublishHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messageHandler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnConnect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connectHandler&lt;/span&gt;
    &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnConnectionLost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connectLostHandler&lt;/span&gt;
    &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;mqtt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Connect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Wait&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Disconnect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;250&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;We will need to define the callback functions as follows&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;messageHandler&lt;/span&gt; &lt;span class="n"&gt;mqtt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MessageHandler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="n"&gt;mqtt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="n"&gt;mqtt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Received message: %s from topic: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Payload&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;connectHandler&lt;/span&gt; &lt;span class="n"&gt;mqtt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnConnectHandler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="n"&gt;mqtt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OptionsReader&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Connected to: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Servers&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;connectLostHandler&lt;/span&gt; &lt;span class="n"&gt;mqtt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectionLostHandler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="n"&gt;mqtt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Connect lost: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&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;It is important to note that these functions will be triggered "on" particular actions. So for example, the &lt;code&gt;messageHandler&lt;/code&gt; function will be triggered whenever the MQTT client receives a message via &lt;code&gt;mqtt.MessageHandler&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And finally, define your publish and subscribe functions as follows:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="n"&gt;mqtt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Message %d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"conf42/go"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Wait&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&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="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="n"&gt;mqtt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;topic&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"conf42/#"&lt;/span&gt;
    &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Wait&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Subscribed to topic: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;topic&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;And that's it! Run the application and observe the results&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

go run go_mqtt.go


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Solace PubSub+ Messaging API for Go
&lt;/h3&gt;

&lt;p&gt;Now that you are an expert on messaging concepts with Go, let's take it up a notch and delve into a more advanced messaging API! We'll be using the &lt;a href="https://pkg.go.dev/solace.dev/go/messaging" rel="noopener noreferrer"&gt;Solace PubSub+ Messaging API for Go&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Install the Solace Native Go API&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

go get solace.dev/go/messaging


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

&lt;/div&gt;
&lt;p&gt;Create a new file and open it with your favourite IDE. I named my file &lt;code&gt;solace_publisher.go&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Import the necessary packages&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;

&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"os"&lt;/span&gt;
    &lt;span class="s"&gt;"os/signal"&lt;/span&gt;
    &lt;span class="s"&gt;"strconv"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;

    &lt;span class="s"&gt;"solace.dev/go/messaging"&lt;/span&gt;
    &lt;span class="s"&gt;"solace.dev/go/messaging/pkg/solace/config"&lt;/span&gt;
    &lt;span class="s"&gt;"solace.dev/go/messaging/pkg/solace/resource"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;Define the configuration parameters to connect to the Solace PubSub+ Broker&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;

&lt;span class="c"&gt;// Configuration parameters&lt;/span&gt;
    &lt;span class="n"&gt;brokerConfig&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServicePropertyMap&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TransportLayerPropertyHost&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;                &lt;span class="s"&gt;"tcp://public.messaging.solace.cloud"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServicePropertyVPNName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;                    &lt;span class="s"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AuthenticationPropertySchemeBasicUserName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"conf42"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AuthenticationPropertySchemeBasicPassword&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"public"&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;Initialize a messaging service and connect to it&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;

&lt;span class="n"&gt;messagingService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;messaging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewMessagingServiceBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FromConfigurationProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;brokerConfig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Connect to the messaging serice&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;messagingService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Connect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&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;Build a Direct Message Publisher and start it&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;

&lt;span class="c"&gt;//  Build a Direct Message Publisher&lt;/span&gt;
&lt;span class="n"&gt;directPublisher&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;builderErr&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;messagingService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateDirectMessagePublisherBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;builderErr&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;builderErr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Start the publisher&lt;/span&gt;
&lt;span class="n"&gt;startErr&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;directPublisher&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;startErr&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;startErr&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;Publish messages in a loop&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;

&lt;span class="n"&gt;msgSeqNum&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;

&lt;span class="c"&gt;//  Prepare outbound message payload and body&lt;/span&gt;
&lt;span class="n"&gt;messageBody&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"Hello from Conf42"&lt;/span&gt;
&lt;span class="n"&gt;messageBuilder&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;messagingService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MessageBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
    &lt;span class="n"&gt;WithProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"application"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"samples"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
    &lt;span class="n"&gt;WithProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"language"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"go"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// Run forever until an interrupt signal is received&lt;/span&gt;
&lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;directPublisher&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsReady&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;msgSeqNum&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
        &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;messageBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BuildWithStringPayload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messageBody&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" --&amp;gt; "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;strconv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Itoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msgSeqNum&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;topic&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TopicOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"conf42/solace/go/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;strconv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Itoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msgSeqNum&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

        &lt;span class="c"&gt;// Publish on dynamic topic with dynamic body&lt;/span&gt;
        &lt;span class="n"&gt;publishErr&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;directPublisher&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;publishErr&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;publishErr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Published message on topic: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetName&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&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;This is the final application.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;

&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"os"&lt;/span&gt;
    &lt;span class="s"&gt;"os/signal"&lt;/span&gt;
    &lt;span class="s"&gt;"strconv"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;

    &lt;span class="s"&gt;"solace.dev/go/messaging"&lt;/span&gt;
    &lt;span class="s"&gt;"solace.dev/go/messaging/pkg/solace/config"&lt;/span&gt;
    &lt;span class="s"&gt;"solace.dev/go/messaging/pkg/solace/resource"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Configuration parameters&lt;/span&gt;
    &lt;span class="n"&gt;brokerConfig&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServicePropertyMap&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TransportLayerPropertyHost&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;                &lt;span class="s"&gt;"tcp://public.messaging.solace.cloud"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServicePropertyVPNName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;                    &lt;span class="s"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AuthenticationPropertySchemeBasicUserName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"conf42"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AuthenticationPropertySchemeBasicPassword&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;messagingService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;messaging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewMessagingServiceBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FromConfigurationProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;brokerConfig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Connect to the messaging serice&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;messagingService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Connect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;//  Build a Direct Message Publisher&lt;/span&gt;
    &lt;span class="n"&gt;directPublisher&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;builderErr&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;messagingService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateDirectMessagePublisherBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;builderErr&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;builderErr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Start the publisher&lt;/span&gt;
    &lt;span class="n"&gt;startErr&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;directPublisher&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;startErr&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;startErr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;msgSeqNum&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;

    &lt;span class="c"&gt;//  Prepare outbound message payload and body&lt;/span&gt;
    &lt;span class="n"&gt;messageBody&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"Hello from Conf42"&lt;/span&gt;
    &lt;span class="n"&gt;messageBuilder&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;messagingService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MessageBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;WithProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"application"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"samples"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;WithProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"language"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"go"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Run forever until an interrupt signal is received&lt;/span&gt;
    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;directPublisher&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsReady&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;msgSeqNum&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
            &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;messageBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BuildWithStringPayload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messageBody&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" --&amp;gt; "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;strconv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Itoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msgSeqNum&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;topic&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TopicOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"conf42/solace/go/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;strconv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Itoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msgSeqNum&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

            &lt;span class="c"&gt;// Publish on dynamic topic with dynamic body&lt;/span&gt;
            &lt;span class="n"&gt;publishErr&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;directPublisher&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;publishErr&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;publishErr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Published message on topic: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetName&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&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="c"&gt;// Handle OS interrupts&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Signal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Interrupt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Block until an OS interrupt signal is received.&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;

    &lt;span class="c"&gt;// Terminate the Direct Publisher&lt;/span&gt;
    &lt;span class="n"&gt;directPublisher&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Terminate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Direct Publisher Terminated? "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;directPublisher&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsTerminated&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="c"&gt;// Disconnect the Message Service&lt;/span&gt;
    &lt;span class="n"&gt;messagingService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Disconnect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Messaging Service Disconnected? "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;messagingService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsConnected&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;And that's it! Run the publisher as follows&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

go run solace_publisher.go


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

&lt;/div&gt;
&lt;p&gt;Note: You can use the &lt;a href="https://docs.solace.com/Cloud/ggs_tryme.htm" rel="noopener noreferrer"&gt;Solace PubSub+ TryMe&lt;/a&gt; tab to connect to the broker and subscribe to any topic you want. Subscribe to topic &lt;code&gt;conf42/solace/&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bonus!&lt;/strong&gt; You can run a subscriber application in another terminal, subscribe to &lt;code&gt;conf42/solace/&amp;gt;&lt;/code&gt;, and observe the results. You can find more about this on the SolaceSample github org.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Challenge!&lt;/strong&gt; Run a publisher and a subscriber in the same application! 🤯&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&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%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/SolaceSamples" rel="noopener noreferrer"&gt;
        SolaceSamples
      &lt;/a&gt; / &lt;a href="https://github.com/SolaceSamples/solace-samples-go" rel="noopener noreferrer"&gt;
        solace-samples-go
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Getting Started Samples for the Solace Go API.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Solace PubSub+ Messaging API for Go&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;This repository contains sample code to showcase how the Solace PubSub+ Go API could be used. You can find:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;/patterns&lt;/code&gt; --&amp;gt; runnable code showcasing different message exchange patters with the PubSub+ Go API.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/howtos&lt;/code&gt; --&amp;gt; code snippets showcasing how to use different features of the API. All howtos are named &lt;code&gt;how_to_*.go&lt;/code&gt; with some sampler files under sub-folders.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Environment Setup&lt;/h2&gt;
&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Install the latest supported version of Go from &lt;a href="https://go.dev/doc/install" rel="nofollow noopener noreferrer"&gt;https://go.dev/doc/install&lt;/a&gt;. Currently, the samples are run and tested against &lt;a href="https://go.dev/dl/" rel="nofollow noopener noreferrer"&gt;Go v1.17&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Install the Solace PubSub+ Messaging API for Go into the root of this directory. This is done by either
&lt;ol&gt;
&lt;li&gt;run &lt;code&gt;go get solace.dev/go/messaging&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Downloading the API archive from the &lt;a href="https://solace.community/group/4-solace-early-access-golang-api" rel="nofollow noopener noreferrer"&gt;Solace Community&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Clone the source code into the root of this repo&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Run Patterns&lt;/h2&gt;

&lt;/div&gt;


&lt;ol&gt;

&lt;li&gt;[Skip if existing] Initialize the directory with Go modules &lt;code&gt;go mod init SolaceSamples.com/PubSub+Go&lt;/code&gt;.&lt;/li&gt;

&lt;li&gt;[For local development] Modify the go.mod file…&lt;/li&gt;

&lt;/ol&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/SolaceSamples/solace-samples-go" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h3&gt;
  
  
  Note on protocol interoperability
&lt;/h3&gt;

&lt;p&gt;Using the Solace PubSub+ Event Broker, you can leverage the protocol translation and interoperability features. Even though the Go API was used to connect to the broker, you can use other Solace APIs and/or open standard protocols to connect to the broker and still have the microservices send and receive messages to each other.&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%2F5pwoa61kble7kq7ss2d3.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%2F5pwoa61kble7kq7ss2d3.png" alt="Solace Protocol translation diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why use Solace native APIs??
&lt;/h3&gt;

&lt;p&gt;You might be wondering, "Why should I use Solace native APIs as opposed to an open-standard open-source messaging protocol like MQTT?" Glad you asked! Check out this blog that talks about the advanced features you can get access to through using Solace's API?&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://solace.com/blog/solace-messaging-apis-event-mesh-features-performance/" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsolace.com%2Fwp-content%2Fuploads%2F2018%2F06%2FDARK_Communication-Between-Microservices-Why-You-Need-Messaging.png" height="auto" class="m-0"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://solace.com/blog/solace-messaging-apis-event-mesh-features-performance/" rel="noopener noreferrer" class="c-link"&gt;
          Use Solace Messaging APIs for Advanced Event Mesh Features and the Best Performance | Solace
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Using Solace’s native messaging APIs gives you access to the full range of PubSub+ Event Broker features and the best performance.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsolace.com%2Fwp-content%2Fthemes%2Forbit-media%2Fresources%2Ffavicons%2Ffavicon-32x32.png"&gt;
        solace.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  This is all cool. How can I know more 👀
&lt;/h2&gt;

&lt;p&gt;In summary, here are some quick links&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;a href="https://solace.community/discussion/1282/go-lets-go-solace-pubsub-messaging-api-for-go-v1-0-0#latest" rel="noopener noreferrer"&gt;Solace Community post&lt;/a&gt; listing a bunch of resources&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/SolaceSamples/solace-samples-go" rel="noopener noreferrer"&gt;Solace PubSub+ Messaging API for Go Samples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://solace.com/blog/go-messaging-api/" rel="noopener noreferrer"&gt;Blog post on the motivation behind a native Solace Go API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=XBkBpFYAHiw&amp;amp;t=76s" rel="noopener noreferrer"&gt;Conf 42 talk on YouTube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to see my colleagues and I during a live streaming session talking about EDA, the Solace PubSub+ Messaging API for Go, and coding (on LIVE television!), check out this event 👀&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/va2ATJSaUzI"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  What about you?
&lt;/h2&gt;

&lt;p&gt;I am curious to hear from the go community!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is it about Golang that you enjoy?&lt;/li&gt;
&lt;li&gt;Have you ever used Golang in an event-driven application?&lt;/li&gt;
&lt;li&gt;What messaging protocols and/or open standards have you used?&lt;/li&gt;
&lt;li&gt;What message brokers do you use?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Open to all sort of discussions, comments, and questions! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/11AuX2SHScQumk/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/11AuX2SHScQumk/giphy.gif" alt="PeaceOut Gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And P.S. You can check out the other talks from Conf42 at &lt;a href="https://www.conf42.com/golang2022" rel="noopener noreferrer"&gt;conf42.com/golang2022&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>eventdriven</category>
      <category>microservices</category>
      <category>conference</category>
    </item>
    <item>
      <title>3 steps to configure Vanilla Forum with Orbit.love</title>
      <dc:creator>Tamimi</dc:creator>
      <pubDate>Tue, 14 Dec 2021 18:27:31 +0000</pubDate>
      <link>https://dev.to/tweettamimi/3-steps-to-configure-vanilla-forum-with-orbitlove-5dap</link>
      <guid>https://dev.to/tweettamimi/3-steps-to-configure-vanilla-forum-with-orbitlove-5dap</guid>
      <description>&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
What's orbit

&lt;ul&gt;
&lt;li&gt;Integrations&lt;/li&gt;
&lt;li&gt;Where's my integration?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Goal&lt;/li&gt;
&lt;li&gt;
1. Extract VF Members

&lt;ul&gt;
&lt;li&gt;Generate VF Token&lt;/li&gt;
&lt;li&gt;Script&lt;/li&gt;
&lt;li&gt;Issues and Improvements&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;2. Import Members to Orbit&lt;/li&gt;
&lt;li&gt;
3. Configure Zapier

&lt;ul&gt;
&lt;li&gt;VF New User Webhook&lt;/li&gt;
&lt;li&gt;Zapier Webhook Actions&lt;/li&gt;
&lt;li&gt;Orbit Step&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Tips and Tricks&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's Orbit?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://orbit.love/"&gt;Orbit&lt;/a&gt; is a platform that helps with understanding your online community. If you are a developer advocate or a community manager then you can consider this platform as the mission control for your community that consolidates and curates all your members and their activities from different places into one place. It's pretty nifty! At &lt;a href="https://solace.community/"&gt;Solace&lt;/a&gt; we use Orbit to better understand our community members and where they gravitate to the most. &lt;/p&gt;

&lt;p&gt;The &lt;a href="https://orbit.love/knowledge-base/understanding-the-orbit-model"&gt;Orbit Model Framework&lt;/a&gt; helps with segmenting community members into different categories depending on their activities and interactions with the community. This framework is based on associating a weighted score for different kind of activities on different platforms. It's important to understand this model for whats coming next 👀&lt;/p&gt;

&lt;h3&gt;
  
  
  Integrations
&lt;/h3&gt;

&lt;p&gt;The nice thing about Orbit is the ability to connect multiple different integration from their natively supported &lt;a href="https://orbit.love/integrations"&gt;integrations&lt;/a&gt;. Meaning that any activity that happens on the platform, for example a tweet or a PR on a github repo, can be ported into your Orbit workspace, associate with the user, and given a particular weight for scoring purposes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where's my integration at?
&lt;/h3&gt;

&lt;p&gt;If your members are hanging out in a platform that is not natively supported by Orbit as an integration, worry not! Since Orbit was built with developers in mind, they naturally have APIs that facilitates the interaction with the platform via importing users and adding activities. &lt;/p&gt;

&lt;p&gt;We use &lt;a href="https://vanillaforums.com"&gt;Vanilla Forum&lt;/a&gt; (VF) as the community forum solution at Solace. Orbit, however, doesn't have a native integration with VF. What's the solution? lets jump into the API! &lt;/p&gt;

&lt;h2&gt;
  
  
  Goal
&lt;/h2&gt;

&lt;p&gt;The problem we wanted to solve is the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Extract all the already existing community members from Vanilla Forum&lt;/li&gt;
&lt;li&gt;Import the members into Orbit&lt;/li&gt;
&lt;li&gt;Integrate any new user activity from VF to Orbit: New Users, Comments, New Discussions. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Luckily, VF has an API we can leverage to extract information from the forum. They also have support for &lt;a href="https://success.vanillaforums.com/kb/articles/262-webhooks"&gt;Webhooks&lt;/a&gt; to facilitate integrations between sites and services whenever any activity happens in the forum. &lt;/p&gt;

&lt;p&gt;Let's cut the chase and get to the core of it!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/xUOwGmsFStnxzIGC2s/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/xUOwGmsFStnxzIGC2s/giphy.gif" alt="" width="480" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Extract existing members. Done once!
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Generate your VF Token
&lt;/h3&gt;

&lt;p&gt;To use the VF APIs, you will first need to generate an Access Token. To do so , follow the steps on &lt;a href="https://success.vanillaforums.com/kb/articles/41-authentication-with-personal-access-tokens"&gt;Authentication With Personal Access Tokens&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Write your script
&lt;/h3&gt;

&lt;p&gt;I wrote a simple nodejs application to extract all the members from VF via their APIs into a CSV file. You can use your programming language of choice.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getUsers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&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;baseURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://solace.community/api/v2/users?expand=extended&amp;amp;page=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;page&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;header_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &amp;lt;Insert Token Here&amp;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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;header_config&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;err&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="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Error fetching content from &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;baseURL&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="nx"&gt;err&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="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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Response status from &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;baseURL&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="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&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="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&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="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&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="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`No content in page &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;page&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="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// CSV list &lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;user&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;isEmployee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;roles&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;roles&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Employee&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&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="nx"&gt;user&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="s2"&gt;, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&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="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;extended&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LinkedInprofileoptional&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="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;extended&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CompanyName&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="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;photoUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, "VF", &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;isEmployee&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="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;extended&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JobTitleoptional&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\n`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

 &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;l&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;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users.csv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&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;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&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;name&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;email&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;github&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;twitter&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;linkedin&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;discorse&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;company&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;avatar_url&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;tags&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;teammate&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;title&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="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users.csv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;39&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;getUsers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&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;h3&gt;
  
  
  Notes
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;The script expects an empty &lt;code&gt;users.csv&lt;/code&gt; file to exist&lt;/li&gt;
&lt;li&gt;The VF API returns the users in several pages. I manually traversed the pages since I knew how many pages I am dealing with for the initial import. You can check out VF's &lt;a href="https://success.vanillaforums.com/kb/articles/40-api-v2-overview#pagination"&gt;Pagination&lt;/a&gt; section for more information&lt;/li&gt;
&lt;li&gt;The generated CSV file follows the &lt;a href="https://orbit.love/knowledge-base/how-to-import-members-and-activities-via-csv"&gt;Orbit CSV import guidelines&lt;/a&gt;. Use this &lt;a href="https://docs.google.com/spreadsheets/d/1huiUe_zpBykjWW5kwzymkd-8HPQAzdRItao-1xgSh6k/edit#gid=2035324798"&gt;Template&lt;/a&gt; if you want to add other tags associated with the members&lt;/li&gt;
&lt;li&gt;The script adds a &lt;code&gt;VF&lt;/code&gt; tag to the users to make sure we can differentiate our forum users from other users. You can add whatever tags your team decides on adding. This is a comma separated list&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Issues and Improvements
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;The Orbit import format does not allow for specifying the &lt;code&gt;joined_at&lt;/code&gt; parameter, so all your imported members will have the joined date as the day you import the members to your workspace&lt;/li&gt;
&lt;li&gt;Pagination could be improved in the script above&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now that you have your CSV file ready, lets import the members to Orbit! &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Import your CSV file to orbit
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to the setting section in your workplace 
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B-iGFlEc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/okcgsnsqh82tve7hl22h.png" alt="Orbit screenshot" width="880" height="377"&gt;
&lt;/li&gt;
&lt;li&gt;Import your CSV File
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---0ip2MO_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/esrevzuf13dy3xkk84lq.png" alt="Orbit screenshot" width="880" height="361"&gt;
&lt;/li&gt;
&lt;li&gt;Wait for the import to finish&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/l4JyOCNEfXvVYEqB2/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/l4JyOCNEfXvVYEqB2/giphy.gif" alt="" width="600" height="338"&gt;&lt;/a&gt;&lt;br&gt;
We're ready to configure Activities! 👇&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Connect Webhooks to Orbit Activities
&lt;/h2&gt;

&lt;p&gt;Vanilla Forum has support for &lt;a href="https://success.vanillaforums.com/kb/articles/262-webhooks"&gt;Webhooks&lt;/a&gt; to integrate with other websites and services. You can use integration services like &lt;a href="https://zapier.com/"&gt;Zapier&lt;/a&gt; or &lt;a href="https://sendgrid.com/"&gt;SendGrid&lt;/a&gt; to leverage the VF Webhooks. In this tutorial I will be using Zapier and assume you already have an account. &lt;/p&gt;

&lt;h3&gt;
  
  
  Vanilla Forum new user webhook
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Create a new zap and search for the Vanilla Forum app 
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wDCOJDH0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/opvfqoumghm7be25aqpd.png" alt="Vanilla Forum Zapier Integration" width="880" height="388"&gt;
&lt;/li&gt;
&lt;li&gt;Configure the connection parameters&lt;/li&gt;
&lt;li&gt;Choose the event you want to trigger the zap with. I chose new user added
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r2vGeIbX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ck1j4jpvafdpof2m37yk.png" alt="Vanilla Forum Zapier Integration" width="880" height="302"&gt;
&lt;/li&gt;
&lt;li&gt;Test the trigger and observe the output
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uBEom3Kw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t0hi0hz4qr2efe1n4pi8.png" alt="Vanilla Forum Zapier Integration" width="880" height="412"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Note
&lt;/h4&gt;

&lt;p&gt;It's important to note that some metadata are not included in the body of the webhook such as the company name and Linkedin profile. Depending on what other parameters you have configured in your VF sign up form, you might want to include other metadata associated with every user.&lt;/p&gt;

&lt;p&gt;🚀 Zapier Webhook Actions for the rescue! &lt;/p&gt;

&lt;h3&gt;
  
  
  Zapier Webhook Actions
&lt;/h3&gt;

&lt;p&gt;We will need to add another step after the Vanilla Forum step. This will leverage VF's REST APIs to query further parameters for the new user.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on the '+' sign to add another step&lt;/li&gt;
&lt;li&gt;Search for "Webhooks By Zapier"
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--O-QvGA4b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i5lwifrm42jpul7c6xh7.png" alt="Webhooks By Zapier" width="880" height="723"&gt;
&lt;/li&gt;
&lt;li&gt;Under the Action event, choose GET
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9DTmgMLI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0pkf130w7o2f6m8m9o6e.png" alt="Webhooks By Zapier GET" width="880" height="423"&gt;
&lt;/li&gt;
&lt;li&gt;Under the Setup Action, fill in the URL &lt;code&gt;https://&amp;lt;your_domain&amp;gt;/api/v2/users/{userID}?expand=extended&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Note that the userID is obtained from the previous step. The &lt;code&gt;expand=extended&lt;/code&gt; parameter is needed to get extra metadata for the newly added user. Check &lt;a href="https://success.vanillaforums.com/kb/articles/394-expanding-user-profile-extender-fields"&gt;Expanding User Profile Extender Fields&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Add an &lt;code&gt;Authorization&lt;/code&gt; Header under the Headers section with a value of &lt;code&gt;Bearer &amp;lt;Insert VF Token&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Click continue and Test the integration
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I7GRuv5x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5q9q1u9jb9x22fnnm73l.png" alt="Webhooks By Zapier GET" width="880" height="967"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Orbit Step: Add new user
&lt;/h3&gt;

&lt;p&gt;Now that we have all the metadata associated with creating a new user, we are ready to add the user to Orbit&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on the '+' sign to add a new step&lt;/li&gt;
&lt;li&gt;Search for orbit
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pBmpqPhB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ucezourx9yi9pyf4neak.png" alt="Orbit Zap" width="880" height="607"&gt;
&lt;/li&gt;
&lt;li&gt;Choose "Create a new Member" from the actions events
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Cw2glPOR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r91g9oij3uvfnhwh8zcp.png" alt="Orbit Zap" width="880" height="460"&gt;
&lt;/li&gt;
&lt;li&gt;Fill in the information either statically (by typing it in) or dynamically (from the output of the previous step)&lt;/li&gt;
&lt;li&gt;Dont forget to add a tag for every activity! For Example &lt;code&gt;VF&lt;/code&gt; for a new user, &lt;code&gt;VF-Discussion&lt;/code&gt; for a new discussion, and &lt;code&gt;VF-Comment&lt;/code&gt; for a new comment&lt;/li&gt;
&lt;li&gt;Click continue and test action&lt;/li&gt;
&lt;li&gt;Turn on the Zap&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And you're done! Now everytime a new user joins your community forum, a webhook is triggered to Zapier, and the Zapier configuration will add that user to Orbit leveraging Orbit's APIs and the details in your step. &lt;/p&gt;

&lt;p&gt;You can follow the same steps for new discussions and new comments webhooks. Make sure you add the right tags for every activity!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/l0Iyl55kTeh71nTXy/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/l0Iyl55kTeh71nTXy/giphy.gif" alt="Done gif" width="480" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips and Tricks
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Adding all the tags and information associated with every activity is extremely crucial. This comes to play and becomes helpful when you want to filter members or activity based on a particular tag&lt;/li&gt;
&lt;li&gt;You can modify the weight for every activity. This can be fine tuned and decided by you and your team. &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>orbit</category>
      <category>vanillaforum</category>
      <category>zapier</category>
      <category>community</category>
    </item>
    <item>
      <title>How to query specific line(s) from a file using GitHub APIs</title>
      <dc:creator>Tamimi</dc:creator>
      <pubDate>Mon, 10 May 2021 19:21:07 +0000</pubDate>
      <link>https://dev.to/tweettamimi/how-to-query-specific-line-s-from-a-file-using-github-apis-ckl</link>
      <guid>https://dev.to/tweettamimi/how-to-query-specific-line-s-from-a-file-using-github-apis-ckl</guid>
      <description>&lt;h1&gt;
  
  
  Permalinks
&lt;/h1&gt;

&lt;p&gt;One of the neat features about GitHub is the generation of permalinks urls that highlights a range of line numbers. This is particularly useful when you want to highlight a chunk of code or a line to show it to someone else. &lt;/p&gt;

&lt;p&gt;To do so, just navigate to the file you want on github and click on one line, hit the &lt;code&gt;Shift&lt;/code&gt; key and click on the end line for the code block. This generates a URL with the highlighted block content that you can then use for sharing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/G95PmK5apUwnpCynwL/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/G95PmK5apUwnpCynwL/giphy.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Edit: feedback based on comment&lt;/strong&gt;&lt;br&gt;
Clicking on the start line number will show the ellipses  button &lt;code&gt;...&lt;/code&gt; hold down shift and click on the end line number. Then click on the overflow button and select &lt;code&gt;Copy permalink&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt;&lt;br&gt;
You can just add &lt;code&gt;#L{start_line}-L{end_line}&lt;/code&gt; to the URL as follows&lt;br&gt;
&lt;code&gt;https://github.com/{org_name}/{repo_name}/{path_to_file}#L{start_line}-L{end_line}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Note: You can &lt;em&gt;perhaps&lt;/em&gt; do the same thing with other version control platforms like bitbucket or gitlabs but I have not checked.&lt;/p&gt;
&lt;h1&gt;
  
  
  Show me the API!
&lt;/h1&gt;

&lt;p&gt;I was recently working on a project that dynamically generates code snippet from files hosted on github. Naturally, I referred to GitHub's APIs to query file content. Simple right? Well let's dig deeper into it. &lt;/p&gt;

&lt;p&gt;Navigating through &lt;a href="https://docs.github.com/en/rest"&gt;Github's APIs&lt;/a&gt;, I was disappointed to find out there is no API that query a &lt;strong&gt;specific line number(s)&lt;/strong&gt; from a file. The &lt;a href="https://docs.github.com/en/github/searching-for-information-on-github/searching-on-github"&gt;Search API&lt;/a&gt; only allows to query the full content of the file. No problem, let's dig into coding logic for post processing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/llKJGxQ1ESmac/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/llKJGxQ1ESmac/giphy.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Show me the code!
&lt;/h1&gt;

&lt;p&gt;To bypass this limitation, I was able to fetch the content of the file using the SearchAPI as follows&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;fetchContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;orgName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;repoName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ref&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;baseURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://api.github.com/repos/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;orgName&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="nx"&gt;repoName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/contents/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;?ref=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&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;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Error fetching content from &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;baseURL&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="nx"&gt;err&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="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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Response status from &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;baseURL&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="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&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="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="c1"&gt;// Content body from github is base64 encoded&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetchContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;orgName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;repoName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This brings in the whole file as text with new line delimiters presented as &lt;code&gt;\n&lt;/code&gt;. You see where I'm going with this 👀&lt;/p&gt;

&lt;p&gt;From here, you can &lt;code&gt;split()&lt;/code&gt; the text content using &lt;code&gt;\n&lt;/code&gt; as the separator and store it in an array&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then simply generate the snippet using a &lt;code&gt;getSlice(content,range)&lt;/code&gt; method&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;snippet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getSlice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where getSlice is defined as follows&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Splits the content given the range a-b or just line number a&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getSlice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;range&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)){&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;"&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="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\r\n&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="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&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;Note: range is passed as a string with a &lt;code&gt;-&lt;/code&gt; delimiter between the start_line and end_line&lt;/p&gt;

&lt;p&gt;And thats it! &lt;/p&gt;

&lt;h1&gt;
  
  
  What about you?
&lt;/h1&gt;

&lt;p&gt;Did you find this useful? I am curious to know if anyone has another approach for this since GitHub does not have an API to do so (yet!) &lt;/p&gt;

</description>
      <category>node</category>
      <category>github</category>
      <category>tutorial</category>
      <category>javascript</category>
    </item>
    <item>
      <title>5 Event-Driven Architectures Myth Busters!</title>
      <dc:creator>Tamimi</dc:creator>
      <pubDate>Fri, 07 May 2021 00:51:14 +0000</pubDate>
      <link>https://dev.to/tweettamimi/5-event-driven-architectures-myth-busters-4gbe</link>
      <guid>https://dev.to/tweettamimi/5-event-driven-architectures-myth-busters-4gbe</guid>
      <description>&lt;h1&gt;
  
  
  Event-Driven Architecture: What's the sitch?
&lt;/h1&gt;

&lt;p&gt;Alright lets face it, there are alot of content talking about how REST APIs are not the best architectural approach for designing a microservices architecture. I wrote a blog post about &lt;a href="https://dev.to/tweettamimi/my-journey-to-learning-event-driven-development-21g1"&gt;My journey to learning EDA&lt;/a&gt; that highlights what event-driven architecture is. Whether you are new to EDA, or have some background with it via dabbling with gRPC, kafka, rabbitMQ, Solace or whatever messaging API, I am here to share with you 5 claims about EDA that I will be BUSTING or CONFIRMING! &lt;br&gt;
&lt;a href="https://i.giphy.com/media/twoz5Rn9lE5vW/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/twoz5Rn9lE5vW/giphy.gif" alt="Myth Busters"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: The original and a bit longer log was originally written on: &lt;a href="https://solace.com/blog/event-driven-architecture-myth-busting-part-1/"&gt;Event-Driven Architecture Myth Busting — Part 1: Five Common EDA Claims&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. I will have to re-design my REST-heavy architecture from scratch to adopt EDA
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🤯 MYTH BUSTED!
&lt;/h3&gt;

&lt;p&gt;Advanced event brokers allow for protocol translation within the broker. What does this mean you might ask? Well, it is very common in any software architecture design approach to have a polyglot of protocols and APIs in an application. Whether you are using REST, or different messaging protocols (MQTT, AMQP, Solace, Kafka...etc) you would want your different microservices communicate with each other. &lt;/p&gt;

&lt;p&gt;This is an extremely valuable asset to an event broker as it provides the organization with an architecturally simple way to distribute business events (order placed, payment initiated, room booked, etc.) to core APIs/services.&lt;/p&gt;

&lt;p&gt;Therefore, we can't claim that a complete overhaul of a REST-only architecture is a must to implement EDA.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. APIs are only asynchronous in EDA
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🤯 MYTH BUSTED!
&lt;/h3&gt;

&lt;p&gt;Implementing EDA in an already existing architecture involves the process of event-enabling the underlying technology. Event-driven architecture does not replace synchronous call-and-response REST altogether, but complements it.&lt;/p&gt;

&lt;p&gt;Having a harmonious interactions between synchronous and asynchronous APIs is inevitable in a digital transformation journey to adopt EDA.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Designing EDA involves lots of moving parts
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✅ CONFIRMED!
&lt;/h3&gt;

&lt;p&gt;Yes this is true. Designing and implementing event-driven system requires a comprehensive strategy, and multiple tools. You are dealing with &lt;em&gt;alot&lt;/em&gt; of things here: topology visualization, application documentation, curating and cataloging the different topics, defining payload schemas for every published events, defining the interaction between applications, pin-pointing the cascading effects of &lt;em&gt;every&lt;/em&gt; change, and ON TOP OF THAT managing access governance! &lt;/p&gt;

&lt;p&gt;Phew thats alot! What's the solution? We'll I am presenting you with two solutions:&lt;/p&gt;

&lt;p&gt;1️⃣ Use the right tools! Microsoft Excel to track event topics, Wiki pages like confluence to document the payload schemas, Git to version control the different schema versions for every topic, Visio diagrams to visualize the constantly changing event-driven architecture topology and finally a communication tool to communicate the changes. And oh wait, one last thing, a project manager to manage all this 😅&lt;/p&gt;

&lt;p&gt;2️⃣ Use an Event Portal! Similar to how REST APIs have an API portal to document and manage the API, Asynchronous Event APIs have an Event Portal that facilitate the design, documentation and governance of events and event-driven applications allowing easier collaboration between different stakeholders.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. An event broker is the only thing you need to implement EDA
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🤯 MYTH BUSTED!
&lt;/h3&gt;

&lt;p&gt;It's important to know that when working on implementing an event-driven architecture the approach should be looked at as a holistic platform composed of a list of tools instead of just one tool (i.e. Event Broker). This is a common misconception that EDA is associated with an event broker only. &lt;/p&gt;

&lt;p&gt;Enabling event-driven architecture requires strategies and tools for documentation; governance to help determine the downstream impact of upcoming changes to apps; events and schemas; and topology visualization of many different microservices, along with the relationship of events connecting applications and application domains.&lt;/p&gt;

&lt;p&gt;And that is why this statement is a myth!&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Using Asynchronous API patterns means processing is done “later”
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🤯 MYTH BUSTED!
&lt;/h3&gt;

&lt;p&gt;I would definitely recommend looking up message exchange patterns (MEP) in event-driven architecture. When doing so, you will see that request-reply is one of the MEPs in EDA which involves an event consumer requesting information from another provider resulting in a bi-directional exchange of information. This behaviour is a proof that asynchronous APIs does not &lt;em&gt;always&lt;/em&gt; mean process later. &lt;/p&gt;

&lt;h1&gt;
  
  
  SHOW ME MORE!
&lt;/h1&gt;

&lt;p&gt;Did you enjoy reading this? Do you want more details about every claim? Say no more! Check out my original blog post here: &lt;a href="https://solace.com/blog/event-driven-architecture-myth-busting-part-1/"&gt;Event-Driven Architecture Myth Busting — Part 1: Five Common EDA Claims&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Do you have OTHER claims that you would like me to bust or confirm?! Comment down below and I would be more than happy to hear your input and thoughts on this. &lt;/p&gt;

&lt;p&gt;P3ace Out ✌️&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/d0NnEG1WnnXqg/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/d0NnEG1WnnXqg/giphy.gif" alt="mic drop"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;P.S Follow me on The Twitter for more content &lt;a class="mentioned-user" href="https://dev.to/tweettamimi"&gt;@tweettamimi&lt;/a&gt;
&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>eventdriven</category>
      <category>kafka</category>
      <category>rest</category>
    </item>
    <item>
      <title>Event-Driven Architecture Myth Busting — Part 1: Five Common EDA Claims</title>
      <dc:creator>Tamimi</dc:creator>
      <pubDate>Thu, 29 Apr 2021 13:50:09 +0000</pubDate>
      <link>https://dev.to/solacedevs/event-driven-architecture-myth-busting-part-1-five-common-eda-claims-e6k</link>
      <guid>https://dev.to/solacedevs/event-driven-architecture-myth-busting-part-1-five-common-eda-claims-e6k</guid>
      <description>&lt;p&gt;Here is a claim that I am willing to drop: event-driven architecture (EDA) is filled with myths. Yep, I said it — and that’s a &lt;strong&gt;fact&lt;/strong&gt;! Now that the elephant is out of the room, let me explain. In this blog post, I will be listing a couple of hand-picked claims about event-driven architecture and, you guessed it, I will either bust them or confirm them as fact. Let’s go ahead and delve further into this exploration with our first five EDA claims!&lt;/p&gt;

&lt;h2&gt;
  
  
  1. I will have to re-design my REST-heavy architecture from scratch to adopt EDA
&lt;/h2&gt;

&lt;p&gt;Poll Results:&lt;a href="https://www.linkedin.com/feed/update/urn:li:activity:6790649427615916032" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsolace.com%2Fwp-content%2Fuploads%2F2021%2F04%2Feda-myth-poll-1-1024x483.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A digital transformation journey strategy explicitly takes that into account! It simply answers the question of “how can I liberate my already existing architecture with its legacy tools, tech, and protocols to modernize my infrastructure without throwing away what I already have”. &lt;a href="https://solace.com/blog/gartner-how-to-choose-an-event-broker/" rel="noopener noreferrer"&gt;Choosing an event broker&lt;/a&gt; to support an event-driven architecture implementation that natively supports protocol translation facilitates the adoption in existing architectures. If the event broker of choice natively supports sending/receiving REST messages, you’ll be able to integrate existing RESTful APIs with messaging APIs and protocols like JMS, MQTT, or AMQP without any extra external adapters, connectors, or bridges.&lt;/p&gt;

&lt;p&gt;This is an extremely valuable asset to an event broker as it provides the organization with an architecturally simple way to distribute business events (order placed, payment initiated, room booked, etc.) to core APIs/services. And since digital transformation journeys to adopting event-driven architecture is an iterative process, this pattern of protocol translation support is valuable in the long-term as it provides a gradual path for adoption of an event-driven architecture. Check out these resources to see how you can &lt;a href="https://solace.com/blog/becoming-an-event-driven-enterprise/" rel="noopener noreferrer"&gt;become an event-driven enterprise in 3 steps&lt;/a&gt; or &lt;a href="https://solace.com/blog/steps-to-implement-event-driven-architecture/" rel="noopener noreferrer"&gt;implement event-driven architecture in 6 steps&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Therefore, claiming that a complete redesign of a REST-only architecture is inevitable when adopting event-driven architecture is a complete… &lt;strong&gt;BUST&lt;/strong&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  2. APIs are only asynchronous in EDA
&lt;/h2&gt;

&lt;p&gt;Poll Results:&lt;br&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/feed/update/urn:li:activity:6792455945944367105" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsolace.com%2Fwp-content%2Fuploads%2F2021%2F04%2Feda-myth-poll-2-1024x483.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A digital transformation journey to adopt event-driven architecture involves the process of event-enabling an already existing architecture. This could include a harmonious interaction between microservices and applications that use &lt;em&gt;synchronous&lt;/em&gt; REST-based APIs and other components of the system that incorporate &lt;em&gt;asynchronous&lt;/em&gt; message-oriented APIs.&lt;/p&gt;

&lt;p&gt;A &lt;a href="https://solace.com/what-is-an-event-broker/" rel="noopener noreferrer"&gt;modern event broker&lt;/a&gt; should support both synchronous and asynchronous message exchange patterns. We’ve always heard the famous “it depends” answer when asking any architectural question about the choice of technology stack in an architecture. And it’s true – choosing a synchronous or asynchronous strategy to implement a particular feature or solve a specific problem does depend on the use-case. That’s why it’s so important to acknowledge that event-driven architecture does &lt;em&gt;not&lt;/em&gt; replace synchronous call-and-response REST altogether, but complements it.&lt;/p&gt;

&lt;p&gt;Hence, the myth that APIs are &lt;em&gt;only&lt;/em&gt; asynchronous in event-driven architecture is… &lt;strong&gt;BUSTED&lt;/strong&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Designing EDA involves lots of moving parts
&lt;/h2&gt;

&lt;p&gt;Designing and implementing event-driven system requires a comprehensive strategy, and multiple tools. These tools are used to track all the events in the system, the different payload schemas, the documentation of the events, the versioning of the topics, and – on top of that – visualizing the overall event-driven architecture topology between the different application domains in your system.&lt;/p&gt;

&lt;p&gt;Organizations use Microsoft Excel to track event topics, schema registries to track the payload schema, Visio diagrams to visualize the constantly changing event-driven architecture topology, wiki pages to document every moving part, and code repositories to store the application code.&lt;/p&gt;

&lt;p&gt;Complete event management toolsets like &lt;a href="https://solace.com/what-is-an-event-portal/" rel="noopener noreferrer"&gt;event portals&lt;/a&gt; facilitate the design, documentation and governance of events and event-driven applications allowing easier collaboration between different stakeholders. Similar to an API portal that makes REST-focused application development easier, an event portal is a one-stop-shop for all things EDA, starting from designing topics, defining payload schemas, visualizing the topology, defining the contracts between applications and application domains within the organization, all the way to &lt;a href="https://solace.com/blog/asyncapi-codegen-microservices-using-spring-cloud-stream/" rel="noopener noreferrer"&gt;code generation from leveraging asynchronous API specifications like AsyncAPI&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Hence, the myth that designing event-driven architecture involves many moving parts is… &lt;strong&gt;CONFIRMED&lt;/strong&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  4. An event broker is the only thing you need to implement EDA
&lt;/h2&gt;

&lt;p&gt;When deciding whether to adopt an EDA strategy, architects and developers should look at this decision through a platform lens instead of just evaluating event brokers. Event-driven architecture should be implemented with a toolset that enables data transformation, connectivity to a wide range of event sources, and tracing events through an &lt;a href="https://solace.com/what-is-an-event-mesh/" rel="noopener noreferrer"&gt;event mesh&lt;/a&gt; that cannot be independently provided by an event broker.&lt;/p&gt;

&lt;p&gt;Enabling event-driven architecture requires strategies and tools for documentation; governance to help determine the downstream impact of upcoming changes to apps; events and schemas; and &lt;a href="https://solace.com/blog/microservice-visualization-google-maps-microservices-architecture/" rel="noopener noreferrer"&gt;topology visualization&lt;/a&gt; of many different microservices, along with the relationship of events connecting applications and application domains.&lt;/p&gt;

&lt;p&gt;All this cannot be successfully implemented with a standalone event broker only, so the myth that an event broker are the only thing you need to implement event-driven architecture is… &lt;strong&gt;BUSTED&lt;/strong&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Using Asynchronous API patterns means processing is done “later”
&lt;/h2&gt;

&lt;p&gt;When &lt;a href="https://solace.com/blog/steps-to-implement-event-driven-architecture/" rel="noopener noreferrer"&gt;implementing event-driven architecture&lt;/a&gt;, a developer can leverage several message exchange patterns, including “fire-and-forget” and request-reply. The fire-and-forget pattern is useful for keeping logs or events for later processing, such as analytics. On the other hand, the request-reply pattern is known for being inherently synchronous, meaning that further processing is blocked until the initial request is completed. I would even argue that implementing a request-reply behavior using &lt;a href="https://solace.com/blog/experience-awesomeness-event-driven-microservices/" rel="noopener noreferrer"&gt;messaging APIs is more powerful than REST APIs&lt;/a&gt; (obviously this is a biased opinion given my focus on messaging).&lt;/p&gt;

&lt;p&gt;The request-reply pattern can be used in the case of an event consumer needing to request information from another provider, requiring a bi-directional exchange of information. Implementing this pattern involves:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A requestor publishing a message on topic A.&lt;/li&gt;
&lt;li&gt;The message is then received by the provider that subscribed to topic A.&lt;/li&gt;
&lt;li&gt;A response is then published by the provider on topic B.&lt;/li&gt;
&lt;li&gt;The response is then received by the original requestor that subscribed on topic B.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Due to the asynchronous nature of the implementation, the requestor can engage in more than one asynchronous request-response conversation at one time.&lt;/p&gt;

&lt;p&gt;So, the myth that using an asynchronous API means that processing is only done later is… &lt;strong&gt;BUSTED&lt;/strong&gt;!&lt;/p&gt;

&lt;h3&gt;
  
  
  Stay tuned for more myth busting (or confirming) in Part 2!
&lt;/h3&gt;

&lt;p&gt;The post &lt;a href="https://solace.com/blog/event-driven-architecture-myth-busting-part-1/" rel="noopener noreferrer"&gt;Event-Driven Architecture Myth Busting — Part 1: Five Common EDA Claims&lt;/a&gt; appeared first on &lt;a href="https://solace.com" rel="noopener noreferrer"&gt;Solace&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>eventdriven</category>
      <category>architecture</category>
      <category>softwaredesign</category>
      <category>microservices</category>
    </item>
    <item>
      <title>My journey to learning Event-Driven development</title>
      <dc:creator>Tamimi</dc:creator>
      <pubDate>Sun, 24 Jan 2021 19:48:28 +0000</pubDate>
      <link>https://dev.to/tweettamimi/my-journey-to-learning-event-driven-development-21g1</link>
      <guid>https://dev.to/tweettamimi/my-journey-to-learning-event-driven-development-21g1</guid>
      <description>&lt;h1&gt;
  
  
  Myth Busters: How to interact with online Web Services?
&lt;/h1&gt;

&lt;p&gt;Legend has it that you can only interact with web services using REST APIs. The same legend also has it that HTTP is the only way of communication on the interweb. And I am here to bust this myth. Thank you in advance for coming to my TED talk.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/eoxomXXVL2S0E/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/eoxomXXVL2S0E/giphy.gif" alt="internet dude gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Elevator pitch
&lt;/h1&gt;

&lt;p&gt;REST over HTTP impose an implied tight coupling between services due to the synchronous point-point nature of the API and protocol respectively. A system based on sending and subscribing to events advocates for a more real-time behaviour and a decoupled architecture hence the name "Event-Driven Architecture" (EDA). The decoupling is achieved by an applications sending events on a topic to a message broker without knowing how the event is controlled or is consumed by. &lt;/p&gt;

&lt;h3&gt;
  
  
  HTTP, REST and EDA walk into a bar
&lt;/h3&gt;

&lt;p&gt;Okay, let me try to break down these concepts in a very simple manner&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;concept&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="s2"&gt;HTTP&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="s2"&gt;definition : &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="nx"&gt;Synchronous&lt;/span&gt; &lt;span class="nx"&gt;point&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;point&lt;/span&gt; &lt;span class="nx"&gt;communication&lt;/span&gt; &lt;span class="nx"&gt;protocol&lt;/span&gt; &lt;span class="nx"&gt;between&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;exchange&lt;/span&gt; &lt;span class="nx"&gt;resources&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;
  },
  1 : {
    &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="nx"&gt;concept&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; : &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="nx"&gt;REST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;,
    &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="nx"&gt;definition&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mechanism leveraging HTTP to send, receive and modify resource one request at a time (request-reply)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="mi"&gt;2&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="s2"&gt;concept&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="s2"&gt;EDA&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="s2"&gt;definition : &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="nx"&gt;Event&lt;/span&gt; &lt;span class="nx"&gt;Driven&lt;/span&gt; &lt;span class="nx"&gt;Architecture&lt;/span&gt; &lt;span class="nx"&gt;based&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;idea&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;sending&lt;/span&gt; &lt;span class="nx"&gt;events&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="nx"&gt;broker&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;topic&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;subscribing&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;them&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;consumption&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;
  }
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have a previous blog post here talking about &lt;a href="https://dev.to/solacedevs/how-i-built-an-event-driven-nodejs-app-on-realtime-covid-19-data-streams-3i98"&gt;How I built an event-driven NodeJS app on realtime COVID-19 data streams&lt;/a&gt;. You can dabble with it if you'd like 🔥&lt;/p&gt;

&lt;h1&gt;
  
  
  What is my Journey to learning event-driven development
&lt;/h1&gt;

&lt;p&gt;I wrote a lengthier blog post that goes into my journey to learning event driven development in details &lt;/p&gt;

&lt;p&gt;In this blog post I talk about &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The history of HTTP and the rise of REST APIs&lt;/li&gt;
&lt;li&gt;Why HTTP and REST are popular&lt;/li&gt;
&lt;li&gt;How our education system is &lt;strong&gt;TIGHTLY&lt;/strong&gt; coupled to industry relevance. In other words, most course outlines are based on "Will this content get a job and dolla dolla billz to our students? If yes then include it in the curriculum!"&lt;/li&gt;
&lt;li&gt;Foundational software and technology concepts and how they map to Event-Driven development concepts&lt;/li&gt;
&lt;li&gt;REST vs. Event-Driven&lt;/li&gt;
&lt;li&gt;Silver bullet when choosing REST vs EDA&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can read more about the post here &lt;a href="https://solace.com/blog/developer-guide-event-driven-development/"&gt;https://solace.com/blog/developer-guide-event-driven-development/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And with that, I will leave you with&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What is your Event-Driven Journey? Have you used event-driven architectures before and how were you introduced to it? Is this your first time hearing about event-driven development and what are you thoughts about it?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/kvQb0oRiksFy4WxWkb/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/kvQb0oRiksFy4WxWkb/giphy.gif" alt="TED Talk"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>http</category>
      <category>rest</category>
      <category>eventdriven</category>
      <category>microservices</category>
    </item>
    <item>
      <title>A Guide for the Developer’s Journey to Event-Driven Development</title>
      <dc:creator>Tamimi</dc:creator>
      <pubDate>Thu, 21 Jan 2021 14:10:41 +0000</pubDate>
      <link>https://dev.to/solacedevs/a-guide-for-the-developer-s-journey-to-event-driven-development-9m</link>
      <guid>https://dev.to/solacedevs/a-guide-for-the-developer-s-journey-to-event-driven-development-9m</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DmEhPWHZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2021/01/solace-blog-featured-image_journey_green.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DmEhPWHZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2021/01/solace-blog-featured-image_journey_green.jpg" alt=""&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;After almost a year working in the world of event-driven architecture and development – and given that I come from a REST API background, which I’m sure a lot of you can identify with – I thought I would share my learning experience. So all aboard! You’re going to embark on my journey to learning event-driven architecture (EDA) from a software developer’s perspective. This journey will take you through:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The origin and evolution of web services&lt;/li&gt;
&lt;li&gt;Popularity of REST APIs and the impact on education&lt;/li&gt;
&lt;li&gt;Mapping REST concepts/terms to their EDA equivalents&lt;/li&gt;
&lt;li&gt;Building web applications: REST vs. event-driven&lt;/li&gt;
&lt;li&gt;Is EDA a silver bullet?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, you can either choose your own adventure and read the section of your choice or jump aboard and take the event-driven development ride from the beginning (recommended!).&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The origin and evolution of web services
&lt;/h2&gt;

&lt;p&gt;Before taking your seat on this event-driven development train, let me give you a quick history lesson on why REST APIs are so popular and how the industry adopted this protocol for most web applications.&lt;/p&gt;

&lt;p&gt;In the late 90s and early 2000s, HTTP started to gain traction in the internet stack by giving people the ability to interact with web services over a network. Web applications were a gold mine in the world of the internet, allowing individuals and businesses to provide services and interact with end users.&lt;/p&gt;

&lt;p&gt;During my undergraduate degree in Communications Engineering, I learned about the OSI model that describes the functions of a networking system through a conceptual framework and a list of abstractions. Web applications rely on the application layer (the only layer the end user interacts with) to transmit information across the lower layers underneath. These web applications and services interact with the application layer through different protocols; HTTP was (and still is) the most popular choice for its simple implementation (relatively speaking!).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://solace.com/wp-content/uploads/2021/01/eda-journey-7-layers.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4rZ9WCb7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2021/01/eda-journey-7-layers.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image Source: &lt;a href="https://www.bmc.com/blogs/osi-model-7-layers/"&gt;https://www.bmc.com/blogs/osi-model-7-layers/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Protocols that communicate with web services and objects over HTTP started rising; the first of which was Simple Object Access Protocol (SOAP). Without delving into the SOAP implementation details, its complexity motivated the rise of REST to communicate with HTTP web services, which made things even simpler to build. There had to be a way for systems to communicate with each other over a protocol. That system architecture is conceptually simple: client-server architecture. A client asks for resources, waits for a response from a server, and performs an action based on this response. Commands through &lt;a href="https://en.wikipedia.org/wiki/Create,_read,_update_and_delete"&gt;CRUD operations&lt;/a&gt; provided a skeleton framework for request-reply and point-to-point communication patterns between services.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://solace.com/wp-content/uploads/2021/01/eda-journey-clients-internet-server.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0itgU0fq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2021/01/eda-journey-clients-internet-server-1024x614.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image source: &lt;a href="https://en.wikipedia.org/wiki/Client%E2%80%93server%5C_model"&gt;https://en.wikipedia.org/wiki/Client%E2%80%93server\_model&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With REST APIs gaining more popularity and industry adoption, more tooling around using REST started evolving. Tooling such as OpenAPI, &lt;a href="https://swagger.io/specification/"&gt;Swagger&lt;/a&gt;, and API Portals facilitated the adoption of REST APIs for building web applications. Automation and code generation tools made learning, understanding, and implementing REST APIs simple, resulting in this &lt;em&gt;implied reputation&lt;/em&gt; that they should be the de facto for system communication and for building web applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interesting Fact&lt;/strong&gt; : In 2000, eBAY was the first enterprise to adopt a REST architecture. Flickr followed in 2004, Amazon in 2006, and then Facebook and Twitter eventually followed suit. At the time of these companies’ adoption of REST architecture, there was no concept of event-driven APIs to interact with web services from a user-facing perspective.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Popularity of REST APIs and the Impact on Education
&lt;/h2&gt;

&lt;p&gt;You might be wondering why REST APIs are so popular. Well, when it comes to learning foundational concepts in the software industry, whether it’s through theoretical education (schooling, online courses, college…etc.) or real-life experiences through on the job training, the learning process is based on two main factors:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Theoretical background and fundamentals&lt;/li&gt;
&lt;li&gt;Industry relevance&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The theoretical background piece is inevitable, and is not influenced by what’s hot and trending. Industry relevance, however, affects the educational content. It only makes sense that course content must be able to draw a direct connection to what’s being implemented in real-life use cases. And let’s face it, most people go to school not just to learn but also get a job and get paid! REST had (and still has) a high industry relevance, so naturally my education path in developing and architecting web applications did not cover learning SOAP services or even event-driven architecture since there wasn’t much in terms of industry relevance. Does this mean that event driven development was completely new to me when I was introduced to it? On the contrary! Next, I’ll explain how the concept of event-driven architecture was ingrained in different areas of learning and how this enabled me to map foundational concepts to EDA fundamentals.&lt;/p&gt;

&lt;p&gt;During my university undergraduate degree, the concepts of event-driven systems and real-time applications were covered as different subjects. The missing element in my event-driven development journey was the bridge between those theoretical concepts and their actual implementation . I will briefly highlight four areas that covered messaging and event-driven systems – Frontend and Game Development, Programming Design Patterns, Networking Fundamentals, and Operating Systems Fundamentals  – followed by a table that maps the theoretical concepts to event-driven architecture lingo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Frontend and Game Development
&lt;/h3&gt;

&lt;p&gt;Interacting with UI elements in front end development is event-driven in nature. A user executes an “event” that &lt;strong&gt;immediately&lt;/strong&gt; “drives” an action in return. For example, a button does not poll its state to check if it is pressed or not, it simply registers an &lt;strong&gt;EventListener&lt;/strong&gt; with a callback function that gets triggered upon an event being fired. A simple implementation takes the following format:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;element&lt;/em&gt;.addEventListener(&lt;em&gt;event, function&lt;/em&gt;);&lt;/p&gt;

&lt;p&gt;Let’s look underneath the hood and digest this further. Since JavaScript is single-threaded and can only do one thing at a time, the browser has an event loop that keeps track of all the events in an event queue which can be accessed through interfaces built on top of the core JavaScript language. Whenever an event occurs in the web browser, the event loop dispatches this event to any registered listener. Sweet and simple. Note that the event loop implements the reactor pattern design discussed in the following section.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://solace.com/wp-content/uploads/2021/01/eda-journey-event-loop.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--91-_OjYO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2021/01/eda-journey-event-loop-1024x710.png" alt="event-driven development"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image source: &lt;a href="https://www.geeksforgeeks.org/what-is-reactor-pattern-in-node-js/"&gt;https://www.geeksforgeeks.org/what-is-reactor-pattern-in-node-js/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In game development, the concepts of EventHandlers and EventDispatchers are very prevalent for asynchronous interactions with a game. The only way to use communication between objects where you don’t care about the target object receiving the event is via EventDispatchers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Programming Design Patterns
&lt;/h3&gt;

&lt;p&gt;Software design patterns present reusable solutions to common problems. For real-time applications, I will give a high-level overview of two common design patterns that present an event-driven approach versus a thread-based approach:&lt;/p&gt;

&lt;h4&gt;
  
  
  Reactor Pattern
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://solace.com/wp-content/uploads/2021/01/eda-journey-reactor-pattern.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6Lnc_Ehy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2021/01/eda-journey-reactor-pattern-1024x457.png" alt="event-driven development"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image source: &lt;a href="https://developers.redhat.com/blog/2019/05/13/building-and-understanding-reactive-microservices-using-eclipse-vert-x-and-distributed-tracing/pasted-image-0-1/"&gt;https://developers.redhat.com/blog/2019/05/13/building-and-understanding-reactive-microservices-using-eclipse-vert-x-and-distributed-tracing/pasted-image-0-1/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This pattern relies on the concepts of dispatching events. It includes a “Reactor” that runs in a separate thread, responding to any I/O events and dispatches the work to “Handlers”. The benefit of the reactor pattern is to avoid having dedicated threads for each message, connection, or request. As seen in the diagram above, events are demultiplexed and dispatched to the responsible handler.&lt;/p&gt;

&lt;h4&gt;
  
  
  Observer Pattern
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://solace.com/wp-content/uploads/2021/01/eda-journey-observer-pattern.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sSjw-u8R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2021/01/eda-journey-observer-pattern-1024x800.png" alt="event-driven development"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image source: &lt;a href="https://subscription.packtpub.com/book/web%5C_development/9781783287314/1/ch01lvl1sec12/the-observer-pattern"&gt;https://subscription.packtpub.com/book/web\_development/9781783287314/1/ch01lvl1sec12/the-observer-pattern&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The observer pattern differs from the reactor pattern in a way that each object maintains a list of its dependents. A change in state for an object will simply trigger a notification (i.e., event) to all the dependents signaling a change. The observer pattern implements a one-to-many relationship where multiple dependents could be “observing” the change in an object.&lt;/p&gt;

&lt;h3&gt;
  
  
  Networking Fundamentals
&lt;/h3&gt;

&lt;p&gt;Recalling the OSI model covered earlier, the network layer was a HUGE help to me when it came to understanding event-driven architecture and development. This layer is responsible for receiving packets of data in the internet stack and delivering them to the intended destination through IP routing. Every packet traveling through the internet has a logical address to its destination (IP) that is handled by the router (middleware hardware) that literally &lt;em&gt;routes&lt;/em&gt; the packet to other destinations in the network. These packets could either be destined to hosts within the network boundary (egress traffic) or traffic coming in from outside the network boundary (Ingress traffic).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://solace.com/wp-content/uploads/2021/01/eda-journey-networking.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A19T3PZD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://solace.com/wp-content/uploads/2021/01/eda-journey-networking.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image source: &lt;a href="https://www.cloudflare.com/learning/network-layer/what-is-routing/"&gt;https://www.cloudflare.com/learning/network-layer/what-is-routing/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The keywords to keep in mind here are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Router&lt;/strong&gt; : a device that contains IP lookup tables mapping from and to destinations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IP&lt;/strong&gt; : the address where the packet is going to or came from.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Host&lt;/strong&gt; : network device that sends/receives packets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Packet format&lt;/strong&gt; : contains metadata about the packet including destination and data content.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Operating Systems Fundamentals
&lt;/h3&gt;

&lt;p&gt;Similar to the reactor pattern discussed earlier, scheduling and threading in an operating system embodies the concepts of dispatching and demultiplexing. Events (I/O, interrupts, thread returns, etc.) are either dispatched to the target endpoint or added to a queue. There are &lt;a href="https://www.tutorialspoint.com/operating_system/os_process_scheduling_algorithms.htm"&gt;six popular scheduling algorithms&lt;/a&gt;, but in a very simplistic overview, scheduling enables asynchronous activities in operating systems and minimizes any resource starvation.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Mapping foundational concepts to their EDA equivalents
&lt;/h2&gt;

&lt;p&gt;Matching the foundational theoretical concepts discussed in the section above to the event-driven architecture equivalent aided me in my event-driven development journey. I summarized them in this table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Foundational Concept&lt;/th&gt;
&lt;th&gt;EDA Equivalent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Front-end &amp;amp; Game Development&lt;/td&gt;
&lt;td&gt;Event Dispatcher&lt;/td&gt;
&lt;td&gt;Publisher&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Event Handler&lt;/td&gt;
&lt;td&gt;Subscriber&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Event Loop&lt;/td&gt;
&lt;td&gt;Event Broker&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Programming Paradigms&lt;/td&gt;
&lt;td&gt;Reactor Pattern&lt;/td&gt;
&lt;td&gt;Event Broker&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Observer Pattern&lt;/td&gt;
&lt;td&gt;Publish/Subscribe&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Networking&lt;/td&gt;
&lt;td&gt;IP Routing&lt;/td&gt;
&lt;td&gt;Topic Routing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Egress and Ingress Routing&lt;/td&gt;
&lt;td&gt;Event Mesh&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IP Address&lt;/td&gt;
&lt;td&gt;Topic&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Packet Anatomy&lt;/td&gt;
&lt;td&gt;Message Anatomy&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Subnet masks&lt;/td&gt;
&lt;td&gt;Wildcard filters&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Operating Systems&lt;/td&gt;
&lt;td&gt;Scheduler&lt;/td&gt;
&lt;td&gt;Event Broker&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Process Scheduling Queues&lt;/td&gt;
&lt;td&gt;Broker Queues&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Threads&lt;/td&gt;
&lt;td&gt;Consumers&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;I/O&lt;/td&gt;
&lt;td&gt;Publish/Subscribe&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h5&gt;
  
  
  In Front-End and Game Development:
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Event Dispatchers&lt;/strong&gt; and &lt;strong&gt;Event Handlers&lt;/strong&gt; relate to &lt;strong&gt;publishers&lt;/strong&gt; and &lt;strong&gt;consumers&lt;/strong&gt; respectively for the nature of publishing and listening to events.&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;event loop&lt;/strong&gt; relates to a &lt;strong&gt;message broker&lt;/strong&gt; due to the nature of dispatching events to registered listeners.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  In the Programming Paradigms category:
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;Reactor&lt;/strong&gt; pattern relates to an &lt;strong&gt;event broker&lt;/strong&gt; through the concept of dispatching events.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Observer&lt;/strong&gt; pattern relates to &lt;strong&gt;Publish/Subscribe message exchange patterns&lt;/strong&gt; through the one-to-many relationship of a publisher to listeners.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  On the Networking front:
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;Every packet has an &lt;strong&gt;IP address&lt;/strong&gt; which is synonymous to &lt;strong&gt;Topics&lt;/strong&gt; that events are sent or received on.&lt;/li&gt;
&lt;li&gt;The concepts of &lt;strong&gt;IP packet&lt;/strong&gt;  &lt;strong&gt;routing&lt;/strong&gt; relates to &lt;strong&gt;message routing&lt;/strong&gt; in the event broker via topic matching.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Egress and Ingress&lt;/strong&gt; traffic routing through multiple networks relates to the behaviour of an &lt;a href="https://solace.com/what-is-an-event-mesh/"&gt;&lt;strong&gt;event mesh&lt;/strong&gt;&lt;/a&gt; in event-driven architecture.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;anatomy of packets&lt;/strong&gt; in a network is broken down in a way that relates to a &lt;a href="https://docs.solace.com/PubSub-Basics/Message-What-Is.htm"&gt;&lt;strong&gt;message anatomy&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The way &lt;strong&gt;subnet masks&lt;/strong&gt; act as filters allowing specific IP ranges relates to using &lt;a href="https://docs.solace.com/PubSub-Basics/Wildcard-Charaters-Topic-Subs.htm"&gt;&lt;strong&gt;wildcards&lt;/strong&gt;&lt;/a&gt; in topic matching and filtering&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  And finally on the Operating Systems front:
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;The behaviour of a &lt;strong&gt;scheduler&lt;/strong&gt; relates to an &lt;strong&gt;event broker&lt;/strong&gt; through dispatching and demultiplexing of events to threads.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Process scheduling queues&lt;/strong&gt;  keeps track of all the processes in the system similar to how a &lt;strong&gt;broker queue&lt;/strong&gt; keeps track of the guaranteed messages on the broker.&lt;/li&gt;
&lt;li&gt;Operating system  &lt;strong&gt;threads&lt;/strong&gt; consume resources similar to how a *&lt;em&gt;consumer *&lt;/em&gt; in an event-driven architecture consumes messages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Input/Output ** operations relate to **Publish/Subscribe message exchange patterns&lt;/strong&gt; in a way that an input device sends instructions to the operating system and the output device receives commands.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Building web applications: REST vs. event-driven
&lt;/h2&gt;

&lt;p&gt;Now that the theoretical background of my journey is covered, I’d like to talk about how this is related to building web applications. If REST APIs have already been adopted for building applications and is considered the de facto solution in many industries, why should we bother ourselves with finding an alternative? Why should we consider an event-driven approach for operational use cases?&lt;/p&gt;

&lt;p&gt;Increased demand for having immediate access to insights had proven that time-critical applications could not rely on REST for real-time feedback and actions. With the recent increase in demand for high availability services, trendy architectural designs like microservices and containerizations started gaining a lot of popularity. Tooling around &lt;a href="https://solace.com/blog/automating-microservices-deployment-strategy-eda-rest/"&gt;microservices deployment strategies&lt;/a&gt; and container orchestration (e.g. Kubernetes, EKS, AKS, Docker Swarms, etc.) also started to become more popular. According to Forbes, &lt;a href="https://www.forbes.com/sites/forbestechcouncil/2019/11/15/data-is-the-new-oil-and-thats-a-good-thing/?sh=57778cd27304"&gt;data is becoming the new oil&lt;/a&gt;, with data being constantly streamed representing a constant flow of events. An example of this is a stock ticker; every time a stock price changes, a new event is created. It’s called “streaming data” because there are thousands of these events resulting in a constant stream of data. Reactive patterns advocate for resilient systems that are message driven as opposed to polling dependent. As per the &lt;a href="https://www.reactivemanifesto.org/"&gt;Reactive Manifesto&lt;/a&gt;, “Today applications are deployed on everything from mobile devices to cloud-based clusters running thousands of multi-core processors. Users expect millisecond response times and 100% uptime.”&lt;/p&gt;

&lt;p&gt;These design requirements motivated me to learn more about event-driven architecture and exposed me to the issues of REST-only and REST-heavy architectural choices for building applications. Keeping the Reactive Manifesto in mind, I’ve summarized a high-level comparative list between REST-based and messaging-based solutions below. Disclaimer: this is not a comprehensive list.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Pros
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Tooling and documentation&lt;/li&gt;
&lt;li&gt;Industry adoption and support&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Simplicity of implementation&lt;br&gt;
| &lt;/p&gt;
&lt;h4&gt;
  
  
  Cons
&lt;/h4&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Built on request-reply communication assumptions. Synchronous in nature.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Point-to-point communication through the adoption of a client-server architecture and reliance on HTTP leading to tight coupling in microservices architectures resulting in a &lt;a href="https://www.gremlin.com/blog/is-your-microservice-a-distributed-monolith/"&gt;distributed monolith&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;REST lock-in. If microservices communicate using REST, that will be the main form of communication preventing interoperability with non-REST applications.&lt;br&gt;
|&lt;br&gt;
| &lt;/p&gt;
&lt;h3&gt;
  
  
  Event-Driven Systems
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h4&gt;
  
  
  Pros
&lt;/h4&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Eventual consistency. The reason why I see this as a pro is because an event-driven system promotes a guaranteed high availability of the data where &lt;strong&gt;eventually&lt;/strong&gt; all microservices in the system will receive the last updated value of the data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reduced coupling between microservices; a message sender does not need to know about any consumer. The only coupling in EDA is a topic hierarchy structure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Loose coupling of applications instead of point-to-point relationships, resulting in easier scaling of the system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Load leveling and shock absorbing though queuing mechanisms.&lt;br&gt;
| &lt;/p&gt;
&lt;h4&gt;
  
  
  Cons
&lt;/h4&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Complexity of handling asynchronous messages when using primitive event brokers. This complexity can be minimized by using an &lt;a href="https://solace.com/what-is-an-event-broker/"&gt;advanced event broker&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Coupling with the messaging infrastructure.&lt;br&gt;
|&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Adopting a REST-driven architectural design has several advantages to it. These include the availability of high quality, industry approved tooling and documentation; industry adoption and support; and simplicity of implementation. However, the drawback to a REST-heavy system is that it’s synchronous in nature. This means that it’s built on a request-reply communication concept, allowing only point-to-point communication: the client must always call the server, the server can not reach out to the client, and the client can not reach out to other clients directly. Through the adoption of a client-server architecture and reliance on HTTP, tight coupling in a microservices architecture could result in a &lt;a href="https://www.gremlin.com/blog/is-your-microservice-a-distributed-monolith/"&gt;distributed monolith&lt;/a&gt;. The one-to-one nature of REST means that a separate REST call is needed for every endpoint which makes it hard to extend the architecture without modifying the clients. I have seen that it is common to build a distributed monolith instead of the intended decoupled microservice architecture, and this leads to a lot of time and money wasted.&lt;/p&gt;

&lt;p&gt;On the other hand, an event-driven system reduces the amount of coupling between microservices. This means that a message sender does not need to know about any consumer; the only coupling in EDA is a &lt;a href="https://solace.com/blog/topic-hierarchy-best-practices/"&gt;topic hierarchy&lt;/a&gt; structure. Loose coupling enables easier scaling of the system and handling of traffic spikes through shock absorbing and queuing mechanisms. In message-oriented systems, applications produce events without controlling how the consumption of those evens is done. This contrasts REST-based systems that rely on synchronous tight coupling between the client and the server.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://solace.com/blog/eventual-consistency-in-microservices/"&gt;Eventual consistency&lt;/a&gt; is intuitively handled in an event-driven system using a message broker, enabling parallel execution of microservices and making sure that each microservice will &lt;em&gt;eventually&lt;/em&gt; come to a state of completion. This allows the system components to eventually become consistent with the state of the system without the need of a two-phase commit or distributed transactions.  However, complexity of handling asynchronous messages when using &lt;a href="https://solace.com/what-is-an-event-broker/"&gt;event brokers&lt;/a&gt; could be a challenge. This challenge is associated with the adoption of any new architecture, which like all other developers, a healthy challenge is encouraging! Another drawback of an event-only driven system is the coupling to the messaging middleware infrastructure, so when adopting an messaging based architecture one should take into account the multi protocol compatibility along with interoperability with other message brokers.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Is EDA a silver bullet?
&lt;/h2&gt;

&lt;p&gt;Neither REST nor event-driven architecture are best for every scenario, and choosing one depends on what you’re trying to accomplish. Large distributed systems and distributed architecture microservices are built on a polyglot of technologies and architectural patterns. An architecture that combines REST and event-driven architecture would deliver the full potential of real-time development and interoperability. &lt;a href="https://www.youtube.com/watch?v=7eKAdLhlT1s"&gt;Event-enabling a REST architecture&lt;/a&gt; allows you to combine traditional REST interactions with publish-subscribe communication, with a message broker acting as the middleware layer for message flow.&lt;/p&gt;

&lt;p&gt;As developers in this modern world, we are no longer just concerned with applications that we write in a silo. Considering the effects of our applications on other parts of the business is becoming more important than ever as the notions of DevOps, microservices, and integrations all become every-day terminologies that a regular developer in the tech industry would hear and use. Furthermore, creating applications that would support a spike in traffic at any point in time is becoming more crucial.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This is my personal event-driven development journey, and like all tech journeys a developer chooses to take, there is always something to learn. I don’t know about you, but I am a developer driven by a challenge and have an urging thirst to solve technical problems using slick tools and architectures! Who knows what architectural trend will come up next with the rise of cloud infrastructures (hybrid/multi-cloud) and new technologies. Regardless of the new tech, it’s important to test it out for yourself, conduct research, keep an open mind, and be ready to learn and grow!&lt;/p&gt;

&lt;p&gt;Thanks for taking the ride with me. Do YOU have an event driven journey or a different experience you’d like to share? Join the &lt;a href="https://solace.community/"&gt;Solace Community&lt;/a&gt; or find me on Twitter &lt;a href="https://twitter.com/TweetTamimi"&gt;@tweetTamimi&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://solace.com/blog/developer-guide-event-driven-development/"&gt;A Guide for the Developer’s Journey to Event-Driven Development&lt;/a&gt; appeared first on &lt;a href="https://solace.com"&gt;Solace&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>fordevelopers</category>
      <category>microservices</category>
      <category>rest</category>
      <category>eventdriven</category>
    </item>
    <item>
      <title>Live session: Event-Driven &amp; code generation with AsyncAPI and Solace 10/06/2020</title>
      <dc:creator>Tamimi</dc:creator>
      <pubDate>Fri, 05 Jun 2020 18:49:41 +0000</pubDate>
      <link>https://dev.to/tweettamimi/live-session-event-driven-code-generation-with-asyncapi-and-solace-10-06-2020-3hk5</link>
      <guid>https://dev.to/tweettamimi/live-session-event-driven-code-generation-with-asyncapi-and-solace-10-06-2020-3hk5</guid>
      <description>&lt;h1&gt;
  
  
  Two types of people
&lt;/h1&gt;

&lt;p&gt;During The 2020 Quarantine, I had the opportunity to delve deep into my thoughts and come up with euphoric discoveries. One of the realization that I came to is that there are two types of people in this world:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Those who sit on the couch and watch Netflix all day&lt;/li&gt;
&lt;li&gt;And those who read blog posts on dev.to and attend live coding sessions to learn new technologies and interact with other developers&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/JQtjrjz75ttYY/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/JQtjrjz75ttYY/giphy.gif" alt="Couch Potato"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since you're reading this now, then you are definitely the second type. So "what is it I will be learning from this live coding session", you may ask? Asynchronous development in an event-driven world! Developing your applications in an event-driven manner is one of the most efficient way to achieve real-time interactions with your data and build a microservices infrastructure. I talk more about this topic and event-driven architectures in &lt;a href="https://dev.to/solacedevs/how-i-built-an-event-driven-nodejs-app-on-realtime-covid-19-data-streams-3i98"&gt;this blogpost&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For those who are not aware of &lt;a href="https://www.asyncapi.com/"&gt;AsyncAPI&lt;/a&gt;, its the industry standard for defining asynchronous APIs to easily build and maintain event-driven architecture. So think Swagger and OpenAPI but for event-driven APIs instead of REST APIs.&lt;/p&gt;

&lt;h1&gt;
  
  
  Taking Event-driven to a META level
&lt;/h1&gt;

&lt;p&gt;Now imagine a world where you can blend event-driven development AND code generation:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3XR0chfiSTtAI/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3XR0chfiSTtAI/giphy.gif" alt="Imagine a world"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Say no more! AsyncAPI also created a generator open source tool that can be used to generate asynchronous event-driven applications based on a predefined AsyncAPI specification file as an input. You can check out &lt;a href="https://github.com/asyncapi/generator#list-of-official-generator-templates"&gt;the list of official generator templates&lt;/a&gt; on the generator github repository. &lt;/p&gt;

&lt;h1&gt;
  
  
  What's the deal with the live coding session?
&lt;/h1&gt;

&lt;p&gt;Glad you asked! An online session will be held on &lt;strong&gt;June 10, 2020 at 10:00 ET&lt;/strong&gt; that covers design to code using &lt;a href="https://solace.com/products/portal/"&gt;Solace PubSub+ Event Portals&lt;/a&gt; + AsyncAPI Code Generation. I will be the host interviewing &lt;a href="https://twitter.com/Mrc0113"&gt;Marc DiPasquale&lt;/a&gt; from Solace and &lt;a href="https://twitter.com/fmvilas"&gt;Fran Méndez&lt;/a&gt;, the founder of AsyncAPI, while we get into an interactive live coding session where we’ll check out the design to code experience. We will also be building an event-driven microservice using Spring Cloud Stream and answer any questions you have.&lt;/p&gt;

&lt;h1&gt;
  
  
  How can I join
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://youtu.be/oQbZf9DTnKc"&gt;YouTube&lt;/a&gt;&lt;br&gt;
&lt;a href="//twitch.tv/solacedevs"&gt;Twitch&lt;/a&gt;&lt;br&gt;
&lt;a href="https://solace.community/"&gt;Solace Community&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;youtubeLink&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://youtu.be/oQbZf9DTnKc"&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;twitchLink&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"twitch.tv/solacedevs"&lt;/span&gt; 

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Youtube Link: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;youtubeLink&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"\nTwitch Link: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;twitchLink&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;So come take part in this interactive session and chat with us on the live stream, I'll give you a shout out if you ask a question 😎&lt;/p&gt;

&lt;p&gt;And to end on a good note, I’d like to leave you with one of my favorite gifs&lt;br&gt;
&lt;a href="https://i.giphy.com/media/llKJGxQ1ESmac/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/llKJGxQ1ESmac/giphy.gif" alt="Hacker nerd programming"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: I am a Developer Advocate at Solace @SolaceDevs&lt;/em&gt;&lt;/p&gt;

</description>
      <category>watercooler</category>
      <category>eventdriven</category>
      <category>livecode</category>
      <category>java</category>
    </item>
    <item>
      <title>LIVE coding during COVID: Solace ft CircleCI</title>
      <dc:creator>Tamimi</dc:creator>
      <pubDate>Wed, 13 May 2020 15:11:03 +0000</pubDate>
      <link>https://dev.to/tweettamimi/live-coding-during-covid-solace-ft-circleci-2fen</link>
      <guid>https://dev.to/tweettamimi/live-coding-during-covid-solace-ft-circleci-2fen</guid>
      <description>&lt;h1&gt;
  
  
  The Developer Species
&lt;/h1&gt;

&lt;p&gt;As a developer, I bet that you also get uneasy stagnating and not leaning something new. We are always on the look for something challenging and "cool" (technically speaking) whether be it the next HOT framework, programming language or reading up on new development patterns that will increase the efficiency of your program (confession session: I'm a victim for this).&lt;/p&gt;

&lt;p&gt;One way I tend to learn about a new technology is by attending in-person conferences and workshop as it gives me the opportunity to have a hands-on learning experience. I particularly enjoy that as it gives me some face-to-face interaction with other technologists and developers, which sparks a lot of interesting conversations and back and forth questions entertaining the inner geek in me. I call this Tamimi's Brainstorming Thought Volleyball™, or TBTV, where we get the opportunity to bounce off ideas and questions with other people. &lt;br&gt;
&lt;a href="https://i.giphy.com/media/oqKZmsUUURlZe/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/oqKZmsUUURlZe/giphy.gif" alt="Beach Volleyball"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;HOWEVER, we are currently surrounded by this thing called COVID (aka rona by some people, dont @ me) which stands in the way of the physical interaction learning process.&lt;/p&gt;
&lt;h1&gt;
  
  
  What's the alternative
&lt;/h1&gt;

&lt;p&gt;You guessed it, LIVE coding sessions! (don't give yourself credit for guessing it, the title of this post gives it away). I'm taking part of a LIVE coding session with Angel from CircleCI where I build an event driven application and learn about build pipelines, a topic that I am alway curious to learn more about. The session will take place today, &lt;strong&gt;Wednesday May 13 2020, at 2:00 pm EST&lt;/strong&gt; and you can check it out on this link &lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=P4ewUZRhVLA"&gt;https://www.youtube.com/watch?v=P4ewUZRhVLA&lt;/a&gt;. If you're more of a twitch streams kind of person, you can also join here &lt;a href="https://www.twitch.tv/circleci"&gt;https://www.twitch.tv/circleci&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  What's in it for me, you may ask
&lt;/h3&gt;

&lt;p&gt;Attending this, you will get the chance to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;didAttend&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Learn about eventdriven development by using Solace PubSub+ Event Broker&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Learn NodeJS if you want to get into it or you're a beginner&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Learn about CircleCI build pipelines&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Teach attendees some cool things!&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So come take part in this interactive session and chat with us on the live stream, I'll give you a shout out if you ask a question 😎&lt;/p&gt;

&lt;h1&gt;
  
  
  What about you?
&lt;/h1&gt;

&lt;p&gt;How do you deal with the lack of physical interaction and attending in-person events? How do you make the learning process more interactive? Have you attended any live coding sessions and actually learnt something from it?&lt;/p&gt;

&lt;p&gt;And to end on a good note, I’d like to leave you with one of my favorite gifs&lt;br&gt;
&lt;a href="https://i.giphy.com/media/llKJGxQ1ESmac/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/llKJGxQ1ESmac/giphy.gif" alt="Hacker nerd programming"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: I am a Developer Advocate at Solace @SolaceDevs&lt;/em&gt;&lt;/p&gt;

</description>
      <category>watercooler</category>
      <category>live</category>
      <category>eventdriven</category>
      <category>node</category>
    </item>
    <item>
      <title>How I used COVID Tracking data to build an event-driven application and learn more Python 🤓</title>
      <dc:creator>Tamimi</dc:creator>
      <pubDate>Sun, 03 May 2020 15:01:23 +0000</pubDate>
      <link>https://dev.to/solacedevs/how-i-used-covid-tracking-data-to-build-and-learn-a-python-event-driven-application-1l44</link>
      <guid>https://dev.to/solacedevs/how-i-used-covid-tracking-data-to-build-and-learn-a-python-event-driven-application-1l44</guid>
      <description>&lt;p&gt;TL;DR – I built a python event driven application leveraging a publicly available real-time stream of COVID-19 data updates using Solace PubSub+ Event Broker as the messaging infrastructure. Check out the source code in this github repo under &lt;code&gt;samples/python&lt;/code&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i3JOwpme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/SolaceLabs"&gt;
        SolaceLabs
      &lt;/a&gt; / &lt;a href="https://github.com/SolaceLabs/covid19-stream-processors"&gt;
        covid19-stream-processors
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Stream Information &amp;amp; Example Applications for Processing JHU and CovidTracking.com COVID-19 data available as streams over Solace
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;
 

&lt;p&gt;Phew! Now that the TL;DR elephant in the room is out of the way, let’s get to the core of it 🐘&lt;/p&gt;

&lt;p&gt;Right now with the situation the world is currently in, some of us are probably thinking “hmm what can I do to contribute back to society? If I can't directly contribute something, what can I learn during quarantine to polish my skills and at the same time build something useful?” I don’t know about you, but I definitely enhanced my baking skills with the amount of banana bread loaves I baked (and ate). Apart from baking, I took this situation as an opportunity to learn new technologies and have something relatable to implement it on (i.e. COVID). I chose Python as the programming language of choice to learn and complement all what I know in event driven architectures.&lt;/p&gt;

&lt;p&gt;In a &lt;a href="https://dev.to/tweettamimi/how-i-built-an-event-driven-nodejs-app-on-realtime-covid-19-data-streams-3i98"&gt;previous blog post&lt;/a&gt;, I discussed how I built an event-driven NodeJS application on real-time COVID-19 data streams. I also covered some background on what event-driven is, why is it important and how to use the publish/subscribe messaging pattern to approach building and EDA application, so I recommend reading it if you haven’t already 🤗 . If JavaScript/NodeJs is not your cup of tea, then worry not! In this blogpost, I will be sharing how I used Python 🐍 to build a simple event driven application using the same COVID-19 streams of data with the same three basic requirements. &lt;/p&gt;
&lt;h1&gt;
  
  
  Tech Stack
&lt;/h1&gt;

&lt;p&gt;Before building any application and work on a project, I start by drafting my architecture design, the different tools to be used and the programming language I need to successfully get an &lt;a href="https://en.wikipedia.org/wiki/Minimum_viable_product"&gt;MVP&lt;/a&gt; up and running. With this approach in mind, I will be using the following tech stack: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Programming Language&lt;/strong&gt;: Python&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Messaging Protocol&lt;/strong&gt;: MQTT&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Message Broker&lt;/strong&gt;: &lt;a href="https://www.solace.dev/"&gt;Solace PubSub+&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data source&lt;/strong&gt;: COVID-19 data provided by the publisher application as per &lt;a href="https://github.com/SolaceLabs/covid19-stream-processors"&gt;this documentation&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that in my tech stack, I didn’t list any REST API or client/server architecture 🤝 Done. Next!&lt;/p&gt;
&lt;h1&gt;
  
  
  1. Environment Setup &amp;amp; Prerequisites
&lt;/h1&gt;

&lt;p&gt;To setup my Python environment, I will be using virtualenv. In a nutshell, virtualenv is a tool used to isolate Python environments by creating a directory structure encapsulating all the installed packages you need in the application you’re building. This way, you wont be contaminating your global Python packages with anything required by your application. You can read more about it &lt;a href="https://docs.python-guide.org/dev/virtualenvs/#lower-level-virtualenv"&gt;here&lt;/a&gt; and on why it is a recommended approach for Python development. &lt;/p&gt;

&lt;p&gt;Note: If you come from a NodeJS background, think in terms of node_modules. &lt;/p&gt;

&lt;p&gt;In a new terminal, execute the following command to create a new directory for your project, setup the Python virtual environment and activate it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir covid_python &amp;amp;&amp;amp; cd "$_" &amp;amp;&amp;amp; virtualenv env &amp;amp;&amp;amp; source env/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now install the &lt;a href="https://pypi.org/project/paho-mqtt/"&gt;paho-mqtt&lt;/a&gt; python package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install paho_mqtt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  2. Skeleton code setup
&lt;/h1&gt;

&lt;p&gt;Create a new &lt;code&gt;covid.py&lt;/code&gt; file and initialize it with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;paho.mqtt.client&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;mqtt&lt;/span&gt;

&lt;span class="c1"&gt;# Solace Broker Info
&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"mr2r9za6fwi0wf.messaging.solace.cloud"&lt;/span&gt;
&lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"covid-public-client"&lt;/span&gt;
&lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"covid19"&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rc&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rc&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"Error Connecting. Return code: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Connected to the COVID PubSub+ Solace Broker!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mqtt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;username_pw_set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;on_connect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;on_connect&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loop_forever&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;What you did above is import the &lt;code&gt;paho-mqtt&lt;/code&gt; package and initialized an mqtt client using the configuration parameters. &lt;/p&gt;

&lt;p&gt;It’s important to note the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;client.loop_forever()&lt;/code&gt; is a blocking function call that processes network traffic, dispatched callbacks and handles reconnecting. You can read more about other loop*() functions in the main &lt;a href="https://pypi.org/project/paho-mqtt/"&gt;documentation page&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;.on_connect&lt;/code&gt; is a function called when the broker responds to our connection request. We assign this callback to the &lt;code&gt;on_connect(client, userdata, flags, rc)&lt;/code&gt; function that will get executed upon a successful connection.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You now have a runnable skeleton to test out our connection. From your terminal execute the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python covid.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see &lt;code&gt;Connected to the COVID PubSub+ Solace Broker!&lt;/code&gt; on your terminal. Saweeet! Connection established 🎉. To stop the execution of the program, press &lt;code&gt;CMD+c&lt;/code&gt; (or &lt;code&gt;Ctrl+c&lt;/code&gt; if you swim in the Windows domain).&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Handle events
&lt;/h2&gt;

&lt;p&gt;To handle the incoming messages from the PubSub+ Broker in an event-driven manner, we have to first subscribe to the topic of interest (according to the &lt;a href="https://github.com/SolaceLabs/covid19-stream-processors#2-choose-your-topics"&gt;available topics&lt;/a&gt;) and handle the messages with the second type of callback function: &lt;code&gt;.on_message&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;paho.mqtt.client&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;mqtt&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rc&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rc&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"Error Connecting. Return code: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Connected to the COVID PubSub+ Solace Broker!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;topics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Subscribing to: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Received message on: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt; %s"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'ascii'&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="c1"&gt;# Broker Info
&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"mr2r9za6fwi0wf.messaging.solace.cloud"&lt;/span&gt;
&lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"covid-public-client"&lt;/span&gt;
&lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"covid19"&lt;/span&gt;

&lt;span class="n"&gt;topics&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s"&gt;"jhu/csse/covid19/test/cases/+/update/Canada/Ontario/#"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"com/covidtracking/states/current/update/New York"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mqtt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;username_pw_set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;on_connect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;on_connect&lt;/span&gt;
&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;on_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;on_message&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loop_forever&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;In the above code program:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I added an &lt;code&gt;on_message(client, data, msg)&lt;/code&gt; function to handle the &lt;code&gt;.on_message&lt;/code&gt; callback from the client. Note the decoding of the received message payload to ascii since we receive the payload in binary format.&lt;/li&gt;
&lt;li&gt;There are subscriptions to two different topics

&lt;ol&gt;
&lt;li&gt;All cases updates in Ontario, Canada obtained from the John Hopkins University data source. I used a test stream.&lt;/li&gt;
&lt;li&gt;All cases updates in New York obtained from The Covid Tracking project data source. Note you can use the topic &lt;code&gt;com/covidtracking/states/current/get/raw&lt;/code&gt; to get raw updates from all the states in the United States&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run the code and wait for updates to come in! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/WoD6JZnwap6s8/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/WoD6JZnwap6s8/giphy.gif" alt="The Matrix binary flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  A note on JSON
&lt;/h3&gt;

&lt;p&gt;Since the returned format of the message payload is in JSON, you can use the python json package to handle, manipulate and &lt;strong&gt;BEAUTIFY&lt;/strong&gt; your output. Here is the full code for your application&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;paho.mqtt.client&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;mqtt&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;json&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rc&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rc&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"Error Connecting. Return code: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Connected to the COVID PubSub+ Solace Broker!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;topics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Subscribing to: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;msg_json_object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'ascii'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;msg_json_pretty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg_json_object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Received message on: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt; %s"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg_json_pretty&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;# Broker Info
&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"mr2r9za6fwi0wf.messaging.solace.cloud"&lt;/span&gt;
&lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"covid-public-client"&lt;/span&gt;
&lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"covid19"&lt;/span&gt;

&lt;span class="n"&gt;topics&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s"&gt;"jhu/csse/covid19/test/cases/+/update/Canada/Ontario/#"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"com/covidtracking/states/current/update/New York"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mqtt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;username_pw_set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;on_connect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;on_connect&lt;/span&gt;
&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;on_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;on_message&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loop_forever&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

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

&lt;/div&gt;



&lt;h1&gt;
  
  
  What’s Next 🤔
&lt;/h1&gt;

&lt;p&gt;I would like to explore more front-end frameworks that I can use in conjunction with Python. So ideally, I will have my Python application communicate with the Solace PubSub+ Event Broker as the backend piece of the application infrastructure and a cool front-end framework to present it. Hey what’s up Django? &lt;/p&gt;

&lt;h1&gt;
  
  
  Closing Remarks
&lt;/h1&gt;

&lt;p&gt;So here is the real question, what did YOU learn during quarantine? Share in the comments below and let’s start a discussion! &lt;/p&gt;

&lt;p&gt;Oh and if you have any recommendations for front end frameworks I would love to 👀 what you have and 👂 your suggestions.&lt;/p&gt;

&lt;p&gt;And to end on a good note, I’d like to leave you with one of my favorite gifs&lt;br&gt;
&lt;a href="https://i.giphy.com/media/llKJGxQ1ESmac/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/llKJGxQ1ESmac/giphy.gif" alt="Hacker nerd programming"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>beginners</category>
      <category>covid19</category>
      <category>showdev</category>
    </item>
    <item>
      <title>How I built an event-driven NodeJS app on realtime COVID-19 data streams</title>
      <dc:creator>Tamimi</dc:creator>
      <pubDate>Thu, 23 Apr 2020 17:06:51 +0000</pubDate>
      <link>https://dev.to/solacedevs/how-i-built-an-event-driven-nodejs-app-on-realtime-covid-19-data-streams-3i98</link>
      <guid>https://dev.to/solacedevs/how-i-built-an-event-driven-nodejs-app-on-realtime-covid-19-data-streams-3i98</guid>
      <description>&lt;p&gt;In this unprecedented time we’re living in, we are all coming together to leverage our joint efforts and use it for COVID19 relief efforts to benefit the public. Everyone is pitching in with their own expertise. Some people have been pitching in by creating PPE products with their 3D printers, some have been developing software and others have been providing technical support for their loved ones or community. In this post, I would like to share how I used a stream of real-time COVID19 data updates to build a NodeJS event-driven application using a simple messaging protocol that can be used to build public facing applications. &lt;/p&gt;

&lt;p&gt;In this application, I will be using the different streams Solace made available to the public for anyone to subscribe to. Documentation on how to use the streams can be found in this github repo. &lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&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%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/SolaceLabs" rel="noopener noreferrer"&gt;
        SolaceLabs
      &lt;/a&gt; / &lt;a href="https://github.com/SolaceLabs/covid19-stream-processors" rel="noopener noreferrer"&gt;
        covid19-stream-processors
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Stream Information &amp;amp; Example Applications for Processing JHU and CovidTracking.com COVID-19 data available as streams over Solace
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;
 
&lt;h1&gt;
  
  
  Research: A bit of background &amp;amp; requirements
&lt;/h1&gt;

&lt;p&gt;Before building this application, I listed out three basic requirements that I wanted to achieve: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Real-time data updates &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Light weight application (I didn’t want to continuously poll or check for new data) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reactive to any data change &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Options
&lt;/h2&gt;

&lt;p&gt;From a higher level perspective, there are two different architectures I could've chosen:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;A synchronous REST-driven approach or &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An Event-driven architecture (EDA) approach &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Option 1: REST
&lt;/h3&gt;

&lt;p&gt;With the first option, there are lots of online resources that I could’ve tapped into including &lt;a href="https://github.com/soroushchehresa/awesome-coronavirus#api" rel="noopener noreferrer"&gt;APIs&lt;/a&gt; or CSV datasets, such as the ones released by John Hopkins University in their &lt;a href="https://github.com/CSSEGISandData/COVID-19" rel="noopener noreferrer"&gt;github repo&lt;/a&gt;. While this is a viable option with lots of online samples and resources, I wanted something more real-time since  &lt;/p&gt;

&lt;p&gt;a) the data is most valuable when its first released (see figure 1 below) and &lt;/p&gt;

&lt;p&gt;b) I wanted an application that &lt;em&gt;reacts&lt;/em&gt; to data updates instead of continuously polling for updates. For example, the CSV file in the JHU github repo is updated once or twice a day. If I used this database, I would have to continuously poll it and check updates. &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%2Fi%2Fnx5jyo3pc1dlh9anx4bd.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%2Fi%2Fnx5jyo3pc1dlh9anx4bd.png" alt="Gartner Stream Processing"&gt;&lt;/a&gt; &lt;em&gt;Figure 1: Value of data diminishes with passing of time&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Also, since I would be dealing with a large data set, I want to only react to new &lt;em&gt;updated data&lt;/em&gt; when changes come in. So a REST approach would not be a light weight implementation. This negates requirement 1 and 2. &lt;/p&gt;
&lt;h3&gt;
  
  
  Option 2: EDA
&lt;/h3&gt;

&lt;p&gt;With an event driven architecture, I can use a publish-subscribe pattern approach to building my application. What is pub-sub you may ask? In a nutshell, it boils down to having a “Publisher” of the data (e.g. COVID-19 data source) and a “Subscriber” to this data (e.g. my NodeJs application) that &lt;em&gt;reacts&lt;/em&gt; only when there is new data published.  &lt;/p&gt;

&lt;p&gt;With the &lt;a href="https://github.com/SolaceLabs/covid19-stream-processors" rel="noopener noreferrer"&gt;PubSub+ COVID-19 Broker&lt;/a&gt; that Solace made available to the public, updates on COVID-19 data are published on different streams. So, application developers wanting to develop an event driven application (IoT, mobile/web app) could consume the stream of data by subscribing to any of the topics available. Since the consumption of this data is framework/platform/language agnostic, I could use any messaging protocols (MQTT, AMQP, JMS) or open APIs (Python, JS, NodeJS…) that support these protocols. I could also use REST!  &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%2Fi%2Fbcz7ymr055ri1hjfid49.jpg" 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%2Fi%2Fbcz7ymr055ri1hjfid49.jpg" alt=" Solace COVID architecture diagram"&gt;&lt;/a&gt; &lt;em&gt;Figure 2: High level end-to-end architecture overview&lt;/em&gt; &lt;/p&gt;
&lt;h1&gt;
  
  
  Decision
&lt;/h1&gt;

&lt;p&gt;So, after evaluating the two options stated above, I decided to take the EDA approach to build my application. Also, since I wanted to use a lightweight messaging API, get real-time COVID-19 updates and be reactive to these updates, EDA was the clear winner. &lt;/p&gt;
&lt;h2&gt;
  
  
  Let’s get to business; well, I mean coding.
&lt;/h2&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%2Fi%2F43t497e1hqaaiz0eg0dv.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%2Fi%2F43t497e1hqaaiz0eg0dv.gif" alt="Coding gif"&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;Based on the supported languages and protocols the Solace PubSub+ broker deals with, I decided to go with using MQTT since there is a native NodeJS API for this &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%2Fi%2F6vnj7mo8h1yw3uq4gl6k.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%2Fi%2F6vnj7mo8h1yw3uq4gl6k.png" alt="languages and protocols Solace support"&gt;&lt;/a&gt; &lt;em&gt;Figure 3: Languages and protocolas supported by Solace&lt;/em&gt; &lt;/p&gt;
&lt;h3&gt;
  
  
  1. Initial setup
&lt;/h3&gt;

&lt;p&gt;Let’s go ahead and start a NodeJS project. Open a new terminal and execute the following command which creates a new directory for your project, initializes it and installs the mqtt package&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="nb"&gt;mkdir &lt;/span&gt;covidproject &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$_&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm init &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm i mqtt 

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Connect to the Broker
&lt;/h3&gt;

&lt;p&gt;Create a new file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="nb"&gt;touch &lt;/span&gt;index.js 

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

&lt;/div&gt;



&lt;p&gt;And open it in your favourite text editor. Insert the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;mqtt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mqtt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;host&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tcp://mr2r9za6fwi0wf.messaging.solace.cloud:1883&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 

    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;covid-public-client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 

    &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;covid19&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mqtt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;connect&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 

    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Connected to COVID PubSub+ Broker!&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What you did above is initialize an &lt;code&gt;mqtt&lt;/code&gt; client and connected to the broker URL using the host and config variables. The mqtt object then returns back signals that your client application can leverage for callback behaviours, in this example it’s the “connect” signal we are listening to &lt;code&gt;client.on(‘connect’)&lt;/code&gt;. We will cover more signals later.  &lt;/p&gt;

&lt;p&gt;Note: the broker URL and credentials are from here &lt;a href="https://github.com/SolaceLabs/covid19-stream-processors#1-connection-information" rel="noopener noreferrer"&gt;https://github.com/SolaceLabs/covid19-stream-processors#1-connection-information&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Now test out your connection by executing the following from terminal&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
node index.js 

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

&lt;/div&gt;



&lt;p&gt;You should see &lt;code&gt;Connected to COVID PubSub+ Broker!&lt;/code&gt; output . Voila! &lt;/p&gt;

&lt;h3&gt;
  
  
  3. Subscribe to the topic
&lt;/h3&gt;

&lt;p&gt;Now that you are connected to the broker, all you need to do is subscribe to topics.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;topics&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; 

    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;jhu/csse/covid19/raw&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="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;connect&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 

    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Connected to COVID PubSub+ Broker!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

    &lt;span class="nx"&gt;topics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;topic&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Subscribing to topic: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

        &lt;span class="nx"&gt;client&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="nx"&gt;topic&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;h3&gt;
  
  
  4. Listen to incoming messages
&lt;/h3&gt;

&lt;p&gt;The second signal we want to listen to is the &lt;code&gt;message&lt;/code&gt; as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&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="nx"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Received message on Topic: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Message:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&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;Note that the received message from the broker is in binary format. To change it to a human readable format we use &lt;code&gt;message.toString()&lt;/code&gt; and we JSON parse it. Note that the messages are sent in JSON format based on the &lt;a href="https://github.com/SolaceLabs/covid19-stream-processors/tree/master/schemas" rel="noopener noreferrer"&gt;schemas&lt;/a&gt; defined in the repo. &lt;/p&gt;

&lt;p&gt;Your final application looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;mqtt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mqtt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 



&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;host&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tcp://mr2r9za6fwi0wf.messaging.solace.cloud:1883&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 

    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;covid-public-client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 

    &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;covid19&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;topics&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; 

   &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;jhu/csse/covid19/raw&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mqtt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 



&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;connect&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 

    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Connected to COVID PubSub+ Broker!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

    &lt;span class="nx"&gt;topics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;topic&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Subscribing to topic: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

        &lt;span class="nx"&gt;client&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="nx"&gt;topic&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="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&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="nx"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Received message on Topic: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Message:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&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;And we’re done! Your application is now connected to the broker and subscribes to one or more topics defined in the array and reacts only when new messages are published. &lt;/p&gt;

&lt;h2&gt;
  
  
  Sample run
&lt;/h2&gt;

&lt;p&gt;I have modified my application to subscribe to all case updates (deaths, active, confirmed and recovered) in Canada Ontario, the recovered cases in Jordan and the confirmed cases in all the provinces in the the United Kingdom using the following topics on the &lt;code&gt;test&lt;/code&gt; stream&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;topics&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;jhu/csse/covid19/test/cases/+/update/Canada/Ontario/#&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="s2"&gt;jhu/csse/covid19/test/cases/recovered/update/Jordan/#&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="s2"&gt;jhu/csse/covid19/test/cases/confirmed/update/United Kingdom/#&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the use of MQTT wild cards ('+' and '#') for topic level matches and multi level matches respectively.&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%2Fi%2Fi40rssmx30dgxw26ulgk.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%2Fi%2Fi40rssmx30dgxw26ulgk.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&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%2Fi%2Fnd6duwmeqih8ly5fbtqs.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%2Fi%2Fnd6duwmeqih8ly5fbtqs.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can check out &lt;a href="https://www.marcd.dev/COVIDStreamViewer/mqtt/mqttListener.html" rel="noopener noreferrer"&gt;https://www.marcd.dev/COVIDStreamViewer/mqtt/mqttListener.html&lt;/a&gt; and subscribe to &lt;code&gt;jhu/csse/covid19/raw&lt;/code&gt; topic for a sample stream viewer. &lt;/p&gt;

&lt;h1&gt;
  
  
  Next steps
&lt;/h1&gt;

&lt;p&gt;When you look at the &lt;a href="https://github.com/SolaceLabs/covid19-stream-processors#2-choose-your-topics" rel="noopener noreferrer"&gt;topic hierarchy&lt;/a&gt;, you can subscribe to different topics and use &lt;a href="https://docs.solace.com/Open-APIs-Protocols/MQTT/MQTT-Topics.htm#Wildcard" rel="noopener noreferrer"&gt;mqtt wildcards&lt;/a&gt; to further customize how your client application consumes the event streams.&lt;/p&gt;

&lt;p&gt;I would happy to see your ideas so feel free to share them and create a pull request to the &lt;a href="https://github.com/SolaceLabs/covid19-stream-processors" rel="noopener noreferrer"&gt;SolaceLabs github repo&lt;/a&gt;! And if you have any questions, leave them in the comments sections below. And feel free to checkout my attempt to build a Python application with the same approach in this &lt;a href="https://dev.to/tweettamimi/how-i-used-covid-tracking-data-to-build-and-learn-a-python-event-driven-application-1l44"&gt;blog post&lt;/a&gt;! &lt;/p&gt;

</description>
      <category>covid19</category>
      <category>javascript</category>
      <category>opensource</category>
      <category>node</category>
    </item>
  </channel>
</rss>
