<?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: Orbital</title>
    <description>The latest articles on DEV Community by Orbital (@orbitalhq).</description>
    <link>https://dev.to/orbitalhq</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%2Forganization%2Fprofile_image%2F7497%2Ffbcb418f-b9f7-4bf0-8f7b-497ba2989fbc.jpg</url>
      <title>DEV Community: Orbital</title>
      <link>https://dev.to/orbitalhq</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/orbitalhq"/>
    <language>en</language>
    <item>
      <title>Converting SOAP APIs to REST, without code 🧼🧰🪄</title>
      <dc:creator>Marty Pitt</dc:creator>
      <pubDate>Tue, 05 Sep 2023 17:21:53 +0000</pubDate>
      <link>https://dev.to/orbitalhq/quickly-modernizing-soap-apis-30gb</link>
      <guid>https://dev.to/orbitalhq/quickly-modernizing-soap-apis-30gb</guid>
      <description>&lt;h4&gt;
  
  
  TLDR:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Soap is an outdated API technology, that takes LOTS of boilerplate.  Sadly, sometimes you don't have a choice.&lt;/li&gt;
&lt;li&gt;We can quickly wrap a SOAP API into REST without code, making it much easier to work with in our web apps&lt;/li&gt;
&lt;li&gt;We can also combine multiple SOAP APIs into a single, purpose-built REST API.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you've ever had to work with SOAP APIs, you know how unpleasant they can be.&lt;/p&gt;

&lt;p&gt;They're cumbersome to call, have heavy amounts of code-gen required, and if you're not using Java or C#... you're already kinda screwed.&lt;/p&gt;

&lt;p&gt;We're gonna to take an old SOAP API (which, lets face it, aren't fun to play with), and repackage it - combining multiple calls into a single REST API.&lt;/p&gt;

&lt;p&gt;Instead of writing piles of boilerplate plumbing code, we'll automate all the integration work with &lt;a href="https://orbitalhq.com"&gt;Orbital&lt;/a&gt; (an open-source data integration platform) and &lt;a href="https://taxilang.org"&gt;Taxi&lt;/a&gt; to annotate the SOAP APIs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RoaWAuE9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6a5r5osmgvkaiy10sj1v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RoaWAuE9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6a5r5osmgvkaiy10sj1v.png" alt="A man staring at a nightmare washing machine" width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Soap...the stuff of nightmares.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Building a Country Info Application
&lt;/h2&gt;

&lt;p&gt;We're working with a public webservice at &lt;a href="http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso"&gt;Oorsprong.org&lt;/a&gt; that provides Country Information.&lt;/p&gt;

&lt;p&gt;It's a powerful API that exposes lots of information about countries, but each piece of information needs a separate call to a SOAP API.&lt;/p&gt;

&lt;p&gt;Each API code takes an ISO Code (eg., &lt;code&gt;GBP&lt;/code&gt; / &lt;code&gt;USA&lt;/code&gt; / &lt;code&gt;NZ&lt;/code&gt;), and returns a small slice of information about a country. (Flag, Currency, Capital City).&lt;/p&gt;

&lt;p&gt;We'd like to grab the data of a few of these services, but without having to write a bunch of SOAP code.&lt;/p&gt;




&lt;h2&gt;
  
  
  Taxi - A quick intro
&lt;/h2&gt;

&lt;p&gt;We'll be using &lt;a href="https://taxilang.org"&gt;Taxi&lt;/a&gt; to help modernize and slice-n-dice this API.  If you haven't heard of Taxi before - you're not alone.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QmCXbFwX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n8amz1vh8e8p57da17dz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QmCXbFwX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n8amz1vh8e8p57da17dz.png" alt="A man driving a taxi" width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Taxi is a relatively new entrant in the API space.  It's an open source metadata language for describing APIs.&lt;/p&gt;

&lt;p&gt;It's goal is to let developers add simple, (but type-safe) &lt;a href="https://orbitalhq.com/blog/2023-05-22-semantic-metadata-101"&gt;tags&lt;/a&gt; into their APIs, so software can understand how different APIs relate to one another.&lt;/p&gt;

&lt;p&gt;It's a simple way of saying "This field is the same as that field", while keeping systems decoupled.&lt;/p&gt;

&lt;p&gt;And the same tags we add into our APIs, we can use to query for data using TaxiQL - Taxi's query language - which replaces all the integration plubming code we'd normally have to write.&lt;/p&gt;




&lt;h3&gt;
  
  
  Getting going
&lt;/h3&gt;

&lt;p&gt;Let's go a little deeper, and break that down into three steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Adding Taxi metadata to the SOAP WSDL (&lt;a href="https://orbitalhq.com/docs/describing-data-sources/soap"&gt;here's&lt;/a&gt; the relevant docs)&lt;/li&gt;
&lt;li&gt;Using &lt;a href="https://orbitalhq.com/docs/querying/writing-queries"&gt;Taxi queries&lt;/a&gt; to build the responses we want to return&lt;/li&gt;
&lt;li&gt;Publishing those queries as REST APIs, with LIVE RELOAD FTW!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The code for this blog is available on &lt;a href="https://github.com/orbitalapi/demos/tree/main/soap-demo"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you find this tutorial useful, why not give us a star on &lt;a href="https://github.com/orbitalapi/orbital"&gt;Github&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Adding metadata to SOAP for fun &amp;amp; profit.
&lt;/h3&gt;

&lt;p&gt;Taxi metadata allows us to sprinkle a few additional tags into our WSDL which let mark data attributes that are the same.&lt;/p&gt;

&lt;p&gt;Later we can use these tags to automate all the SOAP interaction, so we don't have to write any SOAP code ourselves.&lt;/p&gt;

&lt;p&gt;For example, our CountryInfo wsdl has a section dedicated to request / response payloads.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;
&amp;lt;!-- Snippet from our WSDL - Request / Response messages for getting a Country Name --&amp;gt;
&lt;span class="gd"&gt;&amp;lt;xs:element name="CountryName"&amp;gt;
&lt;/span&gt;    &amp;lt;xs:complexType&amp;gt;
       &amp;lt;xs:sequence&amp;gt;
          &amp;lt;xs:element name="sCountryISOCode"
                 type="xs:string" 
&lt;span class="gi"&gt;+                taxi:type="com.demo.IsoCountryCode"/&amp;gt;
&lt;/span&gt;       &amp;lt;/xs:sequence&amp;gt;
    &amp;lt;/xs:complexType&amp;gt;
    &amp;lt;/xs:element&amp;gt;
    &amp;lt;xs:element name="CountryNameResponse"&amp;gt;
    &amp;lt;xs:complexType&amp;gt;
       &amp;lt;xs:sequence&amp;gt;
         &amp;lt;xs:element name="CountryNameResult" 
             type="xs:string" 
&lt;span class="gi"&gt;+            taxi:type="com.demo.CountryName"/&amp;gt;
&lt;/span&gt;       &amp;lt;/xs:sequence&amp;gt;
    &amp;lt;/xs:complexType&amp;gt;
&lt;span class="gd"&gt;&amp;lt;/xs:element&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can summarize this by saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I can send a &lt;code&gt;CountryName&lt;/code&gt; request containing a &lt;code&gt;IsoCountryCode&lt;/code&gt;, and I'll get back a message containing a &lt;code&gt;CountryName&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Elsewhere, we can also use a &lt;code&gt;IsoCountryCode&lt;/code&gt; to get more information, like a &lt;code&gt;CountryFlagUrl&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;
&amp;lt;xs:element name="CountryFlag"&amp;gt;
  &amp;lt;xs:complexType&amp;gt;
     &amp;lt;xs:sequence&amp;gt;
        &amp;lt;xs:element name="sCountryISOCode"
            type="xs:string"
&lt;span class="gi"&gt;+           taxi:type="com.demo.IsoCountryCode"/&amp;gt;
&lt;/span&gt;     &amp;lt;/xs:sequence&amp;gt;
  &amp;lt;/xs:complexType&amp;gt;
&lt;span class="gd"&gt;&amp;lt;/xs:element&amp;gt;
&amp;lt;xs:element name="CountryFlagResponse"&amp;gt;
&lt;/span&gt;  &amp;lt;xs:complexType&amp;gt;
     &amp;lt;xs:sequence&amp;gt;
        &amp;lt;xs:element name="CountryFlagResult"
                type="xs:string"
&lt;span class="gi"&gt;+               taxi:type="com.demo.CountryFlagUrl"/&amp;gt;
&lt;/span&gt;     &amp;lt;/xs:sequence&amp;gt;
  &amp;lt;/xs:complexType&amp;gt;
&lt;span class="gd"&gt;&amp;lt;/xs:element&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's a whole lotta XML, for not much info - which is one of the problems with SOAP - it's just too darn noisy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZBFNyeeh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kav73g662ar8qpe5gdaj.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZBFNyeeh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kav73g662ar8qpe5gdaj.gif" alt="Sarah Lynn - That's Too Much, Man" width="498" height="286"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Using Taxi queries to get the data we want
&lt;/h2&gt;

&lt;p&gt;Now that our WSDL is annotated with Taxi, we can use TaxiQL to do all the heavy lifting for us.&lt;/p&gt;

&lt;p&gt;Rather than generating a bunch of Java classes from the WSDL, we can simply write a taxi query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;given { iso: IsoCountryCode = "NZ"}
find { 
    // Each field comes from a different SOAP service.
    // But taxi keeps this nice and succinct, composing the services
    // together we need on demand
    name: CountryName
    flag: CountryFlagUrl
    currency: CurrencyName
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can send that query to Orbital, and Orbital calls all the SOAP services we need on our behalf, giving us back the data we're looking for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"New Zealand"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"flag"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://www.oorsprong.org/WebSamples.CountryInfo/Flags/New_Zealand.jpg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"currency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"New Zealand Dollars"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Orbital's profiler shows us exactly what happened:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hH54YrxL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4q2i9cycf2o838j8ruw8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hH54YrxL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4q2i9cycf2o838j8ruw8.png" alt="Oribtal Profiler" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Orbital called 3 different SOAP endpoints&lt;/li&gt;
&lt;li&gt;It dealt with all the SOAP Request/Response malarchy&lt;/li&gt;
&lt;li&gt;It plucked the data we want, and gave it back.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And we can drill into the details of each call too:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WXA5UHwx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gqpuowrtyibspn9m91gd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WXA5UHwx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gqpuowrtyibspn9m91gd.png" alt="Call details" width="800" height="634"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Instant REST API
&lt;/h2&gt;

&lt;p&gt;Now that we're happy with the content of our payload, we can quickly turn it into a REST API.&lt;/p&gt;

&lt;p&gt;Simply by checking a query into our project's git repo, and adding an annotation, Orbital gives us a fully working REST API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
@HttpOperation(url = '/api/q/countrydata/{countryCode}', method = 'GET')
query countrydata(@PathVariable("countryCode") countryCode :  IsoCountryCode) {
   given { countryCode }
   find {
       name : CountryName
       flag: CountryFlagUrl
       currency: CurrencyName
       capital: CapitalCityName
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By adding a &lt;code&gt;@HttpOperation&lt;/code&gt; annotation to our query, and saving it our local Taxi project, Orbital instantly exposes a REST API for us.&lt;br&gt;
Rather than hard-coding our query to information about New Zealand, we've put the country code as a part of the path.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@HttpOperation(url = '/api/q/countrydata/{countryCode}', method = 'GET')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, if we call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:9022/api/q/countrydata/NZ 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gives us:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"New Zealand"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"flag"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://www.oorsprong.org/WebSamples.CountryInfo/Flags/New_Zealand.jpg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"currency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"New Zealand Dollars"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"capital"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Wellington"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Live reload for the win
&lt;/h2&gt;

&lt;p&gt;Orbital is live reloading this query, so while we're working locally and making changes to our query, changes are instantly deployed!&lt;/p&gt;

&lt;p&gt;Once deployed, making changes is as simple as pushing to a git repository.&lt;/p&gt;

&lt;p&gt;Check it out:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SePblGro--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xlmdcmz8dauc2jsp8pxe.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SePblGro--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xlmdcmz8dauc2jsp8pxe.gif" alt="Live reload" width="639" height="674"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adding the &lt;code&gt;CapitalCityName&lt;/code&gt; into our request actually added a whole new SOAP request and integration into our query, which Orbital instantly reloaded behind the scenes.&lt;/p&gt;




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

&lt;p&gt;In this blog, we've quickly repackaged a SOAP API into the exact API we wanted, without having to deal with any of the nastiness that &lt;br&gt;
normally comes from dealing with SOAP requests.&lt;/p&gt;

&lt;p&gt;In the process, we've touched on a few of Orbital's handy features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using Taxi metadata in SOAP WSDLs&lt;/li&gt;
&lt;li&gt;Composing together multiple SOAP calls&lt;/li&gt;
&lt;li&gt;Instant REST APIs with live reload&lt;/li&gt;
&lt;li&gt;Viewing profiling data &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The full code to run this demo locally is available on &lt;a href="https://github.com/orbitalapi/demos/tree/main/soap-demo"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is only scratching the surface of what we can do.  Orbital can also stitch this data together with other APIs (such as &lt;a href="https://orbitalhq.com/docs/describing-data-sources/open-api"&gt;REST&lt;/a&gt; / &lt;a href="https://orbitalhq.com/docs/describing-data-sources/protobuf"&gt;gRPC&lt;/a&gt;), call &lt;a href="https://orbitalhq.com/docs/describing-data-sources/aws-services#lambda"&gt;serverless functions&lt;/a&gt;, query our &lt;a href="https://orbitalhq.com/docs/describing-data-sources/databases"&gt;Databases&lt;/a&gt;, or &lt;a href="https://orbitalhq.com/docs/describing-data-sources/connect-kafka-topic"&gt;Kafka queues&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Give us star!
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iM0c1qHT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ls1d8zm26pvbxat92j6w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iM0c1qHT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ls1d8zm26pvbxat92j6w.png" alt="A small boy asking for a star" width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you found this useful, please give our &lt;a href="https://github.com/orbitalapi/orbital"&gt;Github repo&lt;/a&gt; a star!&lt;/p&gt;

</description>
      <category>api</category>
      <category>tutorial</category>
      <category>microservices</category>
      <category>data</category>
    </item>
  </channel>
</rss>
