<?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: Shiv Rai (S_RAI)</title>
    <description>The latest articles on DEV Community by Shiv Rai (S_RAI) (@rai_shiv).</description>
    <link>https://dev.to/rai_shiv</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3772695%2F2e3d2879-a059-4490-8c06-86b081eef8e5.png</url>
      <title>DEV Community: Shiv Rai (S_RAI)</title>
      <link>https://dev.to/rai_shiv</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rai_shiv"/>
    <language>en</language>
    <item>
      <title>Why A Generator Built for the Second Run Makes Sense</title>
      <dc:creator>Shiv Rai (S_RAI)</dc:creator>
      <pubDate>Sun, 04 Oct 2026 18:36:15 +0000</pubDate>
      <link>https://dev.to/rai_shiv/why-a-generator-built-for-the-second-run-makes-sense-53nk</link>
      <guid>https://dev.to/rai_shiv/why-a-generator-built-for-the-second-run-makes-sense-53nk</guid>
      <description>&lt;h2&gt;
  
  
  First impressions
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyd60btjzzy33hmpvief6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyd60btjzzy33hmpvief6.png" alt="Jostraca Homepage" width="800" height="743"&gt;&lt;/a&gt;&lt;br&gt;
At first, I understood little of what Jostraca does. &lt;/p&gt;

&lt;p&gt;The first line, "Regenerate a file tree after manual edits," may raise the question, "Why would someone do that?". Because that's not the normal workflow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scaffold?&lt;/strong&gt;&lt;br&gt;
The examples of scaffolds or starter templates may sound more common and understandable - &lt;br&gt;
"create-next-app" simply creates a Next.js starter app that you can begin customizing. But after you have made edits, there is almost never a need to re-generate the app (by deleting the project and generating it again, or by generating a fresh copy elsewhere). &lt;br&gt;
But that is not what Jostraca does. &lt;br&gt;
It is not related to commands that spin up a starter project with templates you are meant to edit and never touch the generation command again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer?&lt;/strong&gt;&lt;br&gt;
After reading a bit, I started to think "Is it a layer over existing generators?". Consider generators like Prisma Generator: you write the specifications, run the generator, and now have the artifacts needed for your project and can use them. &lt;br&gt;
If Jostraca is a layer between the existing generator and its generated output, you could edit that output and still preserve those edits when regenerating artifacts after specification changes. &lt;br&gt;
And the answer is "NO". Jostraca is not a layer that sits on top of existing generators such as Prisma Generator.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generator Framework&lt;/strong&gt;&lt;br&gt;
Like how Nextjs is a framework for creating websites, Jostraca is a framework for creating generators. &lt;/p&gt;

&lt;p&gt;The homepage might seem a bit ambiguous and not easily understandable but complete the tutorial at &lt;a href="https://jostraca.org/docs/tutorial/" rel="noopener noreferrer"&gt;https://jostraca.org/docs/tutorial/&lt;/a&gt; (or &lt;a href="https://github.com/jostraca/jostraca/blob/main/docs/tutorial.md" rel="noopener noreferrer"&gt;https://github.com/jostraca/jostraca/blob/main/docs/tutorial.md&lt;/a&gt;) and you will have most of the information about how to work with Jostraca.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Jostraca finds its place
&lt;/h2&gt;

&lt;p&gt;Jostraca finds its place among developers who are building generators.&lt;br&gt;
Generators like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SDK generators that need to be regenerated when APIs change.&lt;/li&gt;
&lt;li&gt;Internal company templates that evolve over time.&lt;/li&gt;
&lt;li&gt;Boilerplate systems shared across multiple teams.&lt;/li&gt;
&lt;li&gt;Code generators where developers are expected to customize generated output.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any system or product where regeneration should not erase hours of work is a potential use case for Jostraca.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Jostraca does not find its place
&lt;/h2&gt;

&lt;p&gt;Jostraca does not find its place in one-time scaffolding tools, starter templates, or generators whose output is never expected to be regenerated. If the generation is meant to run only once, then Jostraca has little benefit.&lt;br&gt;
For these cases, a simpler scaffolding approach is both - sufficient and efficient.&lt;/p&gt;

&lt;h2&gt;
  
  
  Following the tutorial
&lt;/h2&gt;

&lt;p&gt;Following the tutorial will give you the knowledge needed to use Jostraca effectively - as the generator framework it is meant to be.&lt;br&gt;
Although you might not understand everything in the tutorial immediately, as you progress in the tutorial, much of it will make sense.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coding Example
&lt;/h2&gt;

&lt;p&gt;To explore Jostraca beyond the tutorial, I built a small &lt;strong&gt;Math Toolkit Generator&lt;/strong&gt;. The generator takes a simple configuration object (project name, version, functions, and feature flags) and produces a small project containing JavaScript functions, documentation, configuration files, and a basic HTML interface.&lt;/p&gt;

&lt;p&gt;Coding example at Github: &lt;a href="https://github.com/ShivRaiGithub/Jostraca-math-toolkit" rel="noopener noreferrer"&gt;https://github.com/ShivRaiGithub/Jostraca-math-toolkit&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The goal was to observe how different files and different modes behave when the generator is run a second time after a developer has modified them.&lt;/p&gt;

&lt;p&gt;The project contains several file types, each using a different regeneration strategy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;basicFunctions.js&lt;/code&gt;&lt;/strong&gt; is fully generated from configuration. If a new function such as &lt;code&gt;power()&lt;/code&gt; is added to the config, the file is completely regenerated. This makes sense because it is pure generated code and should always reflect the latest configuration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;customFunctions.js&lt;/code&gt;&lt;/strong&gt; contains user-owned code and a generated section. On regeneration, only the generated block is updated while user-written functions remain untouched. This allows developers to extend the project safely.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;userNotes.md&lt;/code&gt;&lt;/strong&gt; is protected using &lt;code&gt;JOSTRACA_PROTECT&lt;/code&gt;. Since notes are entirely user-owned content, the generator never modifies the file after creation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;README.md&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;/strong&gt; are regenerated every run because they are derived entirely from the current configuration and should stay synchronized.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;index.html&lt;/code&gt;&lt;/strong&gt; uses Jostraca's merge functionality. Generated UI elements, such as operation buttons, can be updated while preserving user customizations like additional styling or custom sections.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;latest-updates.txt&lt;/code&gt;&lt;/strong&gt; demonstrates preservation. When regenerated, the previous version is stored as a backup, allowing the history of generated output to be retained.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;config-summary.json&lt;/code&gt;&lt;/strong&gt; demonstrates diff mode. Instead of automatically replacing content, Jostraca writes explicit EXISTING and GENERATED blocks so changes can be reviewed before being accepted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are two scripts, &lt;code&gt;run&lt;/code&gt; and &lt;code&gt;run2&lt;/code&gt;, in &lt;code&gt;package.json&lt;/code&gt; that execute the generator using two different configuration files. Running the generator clearly demonstrated how each regeneration strategy behaves and, more importantly, why different files often require different update policies. &lt;/p&gt;

&lt;h2&gt;
  
  
  Observations after working with Jostraca
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Complexity in theory
&lt;/h3&gt;

&lt;p&gt;You might think you understand what Jostraca does at first, but questions start to arise once you think more deeply about it. The complexity is not in using Jostraca. It's in understanding what problem it solves. Most developers are familiar with one-time scaffolding tools, but not with tools designed for regeneration. &lt;/p&gt;

&lt;h3&gt;
  
  
  The Simplicity in working
&lt;/h3&gt;

&lt;p&gt;You only need a single package, &lt;code&gt;jostraca&lt;/code&gt; (installable via &lt;code&gt;npm install jostraca&lt;/code&gt;), to get started.&lt;br&gt;
Even simple generators can be created by executing a single file containing Jostraca code.&lt;/p&gt;

&lt;p&gt;Although understanding the problem Jostraca solves may take some time, getting a basic generator running requires surprisingly little code.&lt;/p&gt;

&lt;h3&gt;
  
  
  The 5 modes
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg7kg36tnh32q473kpj1u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg7kg36tnh32q473kpj1u.png" alt="5-modes" width="800" height="124"&gt;&lt;/a&gt;&lt;br&gt;
Jostraca provides five modes that determine what happens to an already-generated file. The 5 modes being &lt;code&gt;write&lt;/code&gt;, &lt;code&gt;preserve&lt;/code&gt;, &lt;code&gt;present&lt;/code&gt;, &lt;code&gt;diff&lt;/code&gt;,&lt;code&gt;merge&lt;/code&gt; - each enabling a specific action to be taken. This allows different files in a generated project to follow different regeneration policies rather than treating every file the same way.&lt;/p&gt;

&lt;h3&gt;
  
  
  My favorite part
&lt;/h3&gt;

&lt;p&gt;The feature I found most interesting in Jostraca was "JOSTRACA_PROTECT".&lt;br&gt;
This essentially provides a very strong option for the user to safeguard any generated file and prevent any further edits by the generator.&lt;br&gt;
Any file containing this string is protected from modifications triggered by regeneration.&lt;/p&gt;

&lt;h3&gt;
  
  
  A point to note
&lt;/h3&gt;

&lt;p&gt;One behavior that surprised me was template path resolution. When using &lt;code&gt;Fragment&lt;/code&gt; with an HTML template, the &lt;code&gt;from&lt;/code&gt; path is resolved relative to the &lt;strong&gt;output folder&lt;/strong&gt;, not the generator script itself. This meant I had to reference the template from the perspective of &lt;code&gt;./out&lt;/code&gt;, which felt unusual at first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Verdict
&lt;/h2&gt;

&lt;p&gt;Jostraca is not a tool for every developer, and it does not try to be. Most application developers will never need regeneration-aware code generation. However, for developers building generators, SDK tooling, or long-lived templates, Jostraca provides a practical set of mechanisms for handling generated files after users start modifying them. &lt;/p&gt;

</description>
      <category>programming</category>
      <category>opensource</category>
      <category>devtool</category>
      <category>software</category>
    </item>
    <item>
      <title>Event driven systems: Webhook vs EventBridge-style API vs Event Sourcing vs CQRS</title>
      <dc:creator>Shiv Rai (S_RAI)</dc:creator>
      <pubDate>Fri, 18 Sep 2026 14:40:48 +0000</pubDate>
      <link>https://dev.to/rai_shiv/event-driven-systems-webhook-vs-eventbridge-style-api-vs-event-sourcing-vs-cqrs-3gib</link>
      <guid>https://dev.to/rai_shiv/event-driven-systems-webhook-vs-eventbridge-style-api-vs-event-sourcing-vs-cqrs-3gib</guid>
      <description>&lt;h2&gt;
  
  
  What are Event-Driven Systems?
&lt;/h2&gt;

&lt;p&gt;Instead of requesting information or invoking functionality directly, event-driven systems communicate by publishing facts about things that have already occurred.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Order placed&lt;/li&gt;
&lt;li&gt;Payment completed&lt;/li&gt;
&lt;li&gt;User registered&lt;/li&gt;
&lt;li&gt;Invoice generated&lt;/li&gt;
&lt;li&gt;Shipment delivered&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The event itself does not tell consumers what to do. It simply communicates that something happened. Consumers decide independently whether and how to react.&lt;/p&gt;

&lt;p&gt;Modern systems are often composed of many independent services, applications, and teams. Direct communication creates dependencies between those systems. Events reduce coupling by allowing producers and consumers to evolve independently.&lt;/p&gt;

&lt;p&gt;Common use cases include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;System integration&lt;/li&gt;
&lt;li&gt;Business process automation&lt;/li&gt;
&lt;li&gt;Distributed architectures&lt;/li&gt;
&lt;li&gt;Audit and compliance systems&lt;/li&gt;
&lt;li&gt;Event-driven workflows&lt;/li&gt;
&lt;li&gt;Data synchronization&lt;/li&gt;
&lt;li&gt;Reactive applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Messaging systems and event-driven systems are often used together, but they are not the same thing. Messaging systems provide transport infrastructure, while event-driven systems define how systems communicate and coordinate through events.&lt;/p&gt;

&lt;p&gt;This article covers: Webhook, EventBridge-style API, Event Sourcing, CQRS&lt;/p&gt;

&lt;h3&gt;
  
  
  Event-Driven Integration vs Event-Driven Architecture
&lt;/h3&gt;

&lt;p&gt;This category contains two related but distinct concepts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Event-Driven Integration&lt;/strong&gt; focuses on moving events between systems.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Webhooks&lt;/li&gt;
&lt;li&gt;EventBridge-style APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is integration and event distribution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Event-Driven Architecture (EDA)&lt;/strong&gt; focuses on how applications are internally designed around events.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Event Sourcing&lt;/li&gt;
&lt;li&gt;CQRS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is modeling, storing, and processing business behavior through events.&lt;/p&gt;

&lt;p&gt;A useful rule of thumb:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Integration technologies help systems communicate.&lt;/li&gt;
&lt;li&gt;Architectural patterns help systems organize and process information internally.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Purpose
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Primary Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Webhooks&lt;/td&gt;
&lt;td&gt;Event-Driven Integration Mechanism&lt;/td&gt;
&lt;td&gt;Notify external systems when events occur&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EventBridge-style APIs&lt;/td&gt;
&lt;td&gt;Event Routing &amp;amp; Integration Platform&lt;/td&gt;
&lt;td&gt;Distribute events across multiple systems and consumers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Event Sourcing&lt;/td&gt;
&lt;td&gt;Architectural Pattern&lt;/td&gt;
&lt;td&gt;Store application state as a sequence of events&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CQRS&lt;/td&gt;
&lt;td&gt;Architectural Pattern&lt;/td&gt;
&lt;td&gt;Separate command and query responsibilities&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These technologies are frequently combined:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A webhook may notify an external system about an event generated internally.&lt;/li&gt;
&lt;li&gt;EventBridge-style platforms may distribute events originating from Event Sourcing systems.&lt;/li&gt;
&lt;li&gt;Event Sourcing and CQRS are often used together to build event-driven applications.&lt;/li&gt;
&lt;li&gt;CQRS systems frequently consume events transported through messaging infrastructure.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Decision Tree
&lt;/h2&gt;

&lt;p&gt;Integration and internal architecture are independent decisions — a system may need one, the other, or both at the same time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How should events be integrated externally?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Webhooks&lt;/strong&gt; are usually the simplest choice for notifying external systems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EventBridge-style APIs&lt;/strong&gt; become valuable when events must be routed to multiple consumers or across many systems.
&lt;/li&gt;
&lt;/ul&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TD

A1[How should events be&amp;lt;br/&amp;gt;integrated externally?] --&amp;gt; B1{Need simple notifications&amp;lt;br/&amp;gt;to external systems?}

B1 --&amp;gt;|Yes| WEBHOOKS[Webhooks]
B1 --&amp;gt;|No — multiple consumers&amp;lt;br/&amp;gt;or systems involved| EVENTBRIDGE[EventBridge-style APIs]&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;strong&gt;How should events be handled internally?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Event Sourcing&lt;/strong&gt; is most useful when event history itself becomes a business requirement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CQRS&lt;/strong&gt; is most useful when read and write workloads have significantly different requirements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event Sourcing + CQRS&lt;/strong&gt; often appears in complex event-driven systems where auditability, scalability, and specialized read models are important.
&lt;/li&gt;
&lt;/ul&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TD

A2[How should events be&amp;lt;br/&amp;gt;handled internally?] --&amp;gt; D{Need a complete historical&amp;lt;br/&amp;gt;record of state changes?}

D --&amp;gt;|No| E{Need independent read and&amp;lt;br/&amp;gt;write models or optimized queries?}

E --&amp;gt;|No| F[Traditional Architecture]
E --&amp;gt;|Yes| CQRSONLY[CQRS Alone]

D --&amp;gt;|Yes| G{Need independent read and&amp;lt;br/&amp;gt;write models or optimized queries?}

G --&amp;gt;|No| ES[Event Sourcing Alone]
G --&amp;gt;|Yes| ESCQRS[Event Sourcing + CQRS]&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;A system might, for example, use Webhooks for external notifications while internally combining Event Sourcing with CQRS — the two trees are meant to be walked separately, not as a single either/or choice.&lt;/p&gt;




&lt;h2&gt;
  
  
  Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Webhooks&lt;/th&gt;
&lt;th&gt;EventBridge-style APIs&lt;/th&gt;
&lt;th&gt;Event Sourcing&lt;/th&gt;
&lt;th&gt;CQRS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Category&lt;/td&gt;
&lt;td&gt;Event-Driven Integration&lt;/td&gt;
&lt;td&gt;Event Routing &amp;amp; Integration&lt;/td&gt;
&lt;td&gt;Architectural Pattern&lt;/td&gt;
&lt;td&gt;Architectural Pattern&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Abstraction Level&lt;/td&gt;
&lt;td&gt;Integration Mechanism&lt;/td&gt;
&lt;td&gt;Event Distribution Platform&lt;/td&gt;
&lt;td&gt;State Management Pattern&lt;/td&gt;
&lt;td&gt;Read/Write Separation Pattern&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Primary Purpose&lt;/td&gt;
&lt;td&gt;Notify external systems&lt;/td&gt;
&lt;td&gt;Route and distribute events&lt;/td&gt;
&lt;td&gt;Store state changes as events&lt;/td&gt;
&lt;td&gt;Separate commands and queries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stores Events?&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Sometimes platform-dependent&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Event Routing?&lt;/td&gt;
&lt;td&gt;Basic&lt;/td&gt;
&lt;td&gt;Core capability&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;External Integration?&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Indirectly&lt;/td&gt;
&lt;td&gt;Indirectly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Internal Architecture?&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Historical Replay?&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Platform-dependent&lt;/td&gt;
&lt;td&gt;Core capability&lt;/td&gt;
&lt;td&gt;No — only available when paired with Event Sourcing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complexity&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Medium to High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Typical Use Cases&lt;/td&gt;
&lt;td&gt;Third-party integrations, notifications&lt;/td&gt;
&lt;td&gt;Event distribution, cloud integrations&lt;/td&gt;
&lt;td&gt;Auditability, financial systems, workflow tracking&lt;/td&gt;
&lt;td&gt;High-scale systems, specialized read models&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strengths&lt;/td&gt;
&lt;td&gt;Simple, widely supported, easy adoption&lt;/td&gt;
&lt;td&gt;Centralized event routing and fan-out&lt;/td&gt;
&lt;td&gt;Complete event history and replayability&lt;/td&gt;
&lt;td&gt;Flexible scaling and optimized read/write paths&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Weaknesses&lt;/td&gt;
&lt;td&gt;Limited routing and reliability guarantees&lt;/td&gt;
&lt;td&gt;Additional infrastructure and operational complexity&lt;/td&gt;
&lt;td&gt;Significant modeling and operational complexity&lt;/td&gt;
&lt;td&gt;Additional architectural complexity&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Webhooks
&lt;/h2&gt;

&lt;p&gt;Webhooks emerged in the mid-2000s. Webhooks were never a formal protocol. They evolved as a practical integration pattern. Early APIs polled data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your App
    |
GET /status
    |
No Change

Wait

GET /status
    |
No Change

Wait

GET /status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As SaaS products grew, polling became inefficient.&lt;/p&gt;

&lt;p&gt;Companies needed a better way to notify customers about events.&lt;/p&gt;

&lt;p&gt;Webhooks answer: How can one system notify another system immediately when something happens?&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Consumer
   |
"Anything new?"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;repeatedly,&lt;/p&gt;

&lt;p&gt;the producer says:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"I'll call you when
something happens."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This transformed API integrations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Webhooks think in callbacks
&lt;/h3&gt;

&lt;p&gt;Core assumption: The consumer provides a URL and waits for events.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client ---&amp;gt; Server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client gives URL

Server ---&amp;gt; Client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The direction reverses.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Suppose a payment succeeds.&lt;/p&gt;

&lt;p&gt;Provider sends:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /webhook

Content-Type: application/json
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Body:&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;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"payment.succeeded"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&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;Your application receives:&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;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/webhook&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;req&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="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="nx"&gt;req&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&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;Output:&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;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"payment.succeeded"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&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;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Extremely simple&lt;/td&gt;
&lt;td&gt;Reliability must be handled carefully&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Real-time notifications&lt;/td&gt;
&lt;td&gt;Consumer must expose a public endpoint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Eliminates polling&lt;/td&gt;
&lt;td&gt;Duplicate deliveries can occur&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uses standard HTTP&lt;/td&gt;
&lt;td&gt;Debugging failures can be difficult&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Easy cross-company integrations&lt;/td&gt;
&lt;td&gt;No built-in replay mechanism&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Widely supported by SaaS platforms&lt;/td&gt;
&lt;td&gt;Not ideal for high-volume streams&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Low infrastructure requirements&lt;/td&gt;
&lt;td&gt;Limited delivery guarantees&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  EventBridge-Style APIs
&lt;/h2&gt;

&lt;p&gt;Cloud-native event buses emerged in the late 2010s as cloud providers looked to formalize the producer-announces, consumers-react pattern as a managed service. AWS EventBridge launched in 2019, followed by comparable services like Azure Event Grid and Google Eventarc. These platforms popularized event-driven integration at scale, giving teams a managed event bus instead of building and operating one themselves.&lt;/p&gt;

&lt;p&gt;As systems became more distributed, organizations ended up with architectures like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Service
     |
     +--&amp;gt; Email Service
     |
     +--&amp;gt; Analytics
     |
     +--&amp;gt; Billing
     |
     +--&amp;gt; CRM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every new consumer required another integration.&lt;/p&gt;

&lt;p&gt;Over time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;One Event
      |
Ten Integrations
      |
Twenty Integrations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;became difficult to manage. EventBridge-style systems answer: How can services publish events once and allow anyone to react without creating direct integrations?&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Producer
   |
Many Consumers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;they introduce:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Producer
   |
Event Bus
   |
Many Consumers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The producer knows only about the bus.&lt;/p&gt;

&lt;h3&gt;
  
  
  EventBridge thinks in business events
&lt;/h3&gt;

&lt;p&gt;Core assumption: Systems should announce facts, not call other systems.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Order Service
   |
Call Email Service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Order Service
   |
OrderCreated Event
   |
Event Bus
   |
Email Service Reacts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Publish Event&lt;/strong&gt;&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;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"orders"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"OrderCreated"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&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;"orderId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;123&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;p&gt;&lt;strong&gt;Event Rule&lt;/strong&gt;&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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"OrderCreated"&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;&lt;strong&gt;Target&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Email Service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When an order is created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Order Service
      |
OrderCreated
      |
Event Bus
      |
Email Service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The email service automatically receives the event.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Loose coupling between services&lt;/td&gt;
&lt;td&gt;Harder debugging and tracing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Easy to add new consumers&lt;/td&gt;
&lt;td&gt;Eventual consistency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Excellent for event-driven systems&lt;/td&gt;
&lt;td&gt;Event schema versioning challenges&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Centralized routing rules&lt;/td&gt;
&lt;td&gt;Hidden dependencies can emerge&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strong cloud integration&lt;/td&gt;
&lt;td&gt;Not suitable for request/response&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scales organizationally&lt;/td&gt;
&lt;td&gt;Added architectural complexity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enables automation workflows&lt;/td&gt;
&lt;td&gt;Less predictable execution paths&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Event Sourcing
&lt;/h2&gt;

&lt;p&gt;Event Sourcing became a mainstream architectural pattern around 2008–2012.&lt;/p&gt;

&lt;p&gt;Most applications store current state and lose history.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;500 -&amp;gt; 700 -&amp;gt; 400 -&amp;gt; 900
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After updates, only 900 remains.&lt;/p&gt;

&lt;p&gt;Organizations wanted auditability, traceability, and rebuildability without relying on fragile audit tables. Event Sourcing answers: What if we stored every change instead of only the latest state?&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Current Balance = 900
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;store:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AccountOpened
MoneyDeposited(200)
MoneyWithdrawn(300)
MoneyDeposited(500)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The current state can always be reconstructed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Event Sourcing thinks in facts, not state
&lt;/h3&gt;

&lt;p&gt;Core assumption: The sequence of events matters more than the current state.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User
------
Name: Alice
Plan: Pro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;store:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;UserRegistered
PlanUpgraded
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Current state becomes a derived value.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Traditional CRUD&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;accounts&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Balance = 500
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Previous history may be lost.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Event Sourcing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Append event:&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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MoneyDeposited"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&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;Then:&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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MoneyWithdrawn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&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;Current balance is computed from events:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+100
-50
----
50
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Complete audit trail&lt;/td&gt;
&lt;td&gt;Significant complexity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Event replay capability&lt;/td&gt;
&lt;td&gt;Event schema evolution challenges&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time-travel debugging&lt;/td&gt;
&lt;td&gt;Eventual consistency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strong compliance support&lt;/td&gt;
&lt;td&gt;Steep learning curve&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Natural fit for event-driven systems&lt;/td&gt;
&lt;td&gt;Storage growth over time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Easier historical analysis&lt;/td&gt;
&lt;td&gt;More infrastructure and tooling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rebuild projections anytime&lt;/td&gt;
&lt;td&gt;Overkill for simple CRUD systems&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  CQRS
&lt;/h2&gt;

&lt;p&gt;CQRS (Command Query Responsibility Segregation) was introduced by Greg Young around 2010.&lt;/p&gt;

&lt;p&gt;Most applications use a single model for both:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Reading Data
Writing Data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Table
      |
 Read Users
 Update Users
 Delete Users
 Create Users
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works well initially.&lt;/p&gt;

&lt;p&gt;But large systems often discover that read traffic doesn't match write traffic.&lt;/p&gt;

&lt;p&gt;For example, Instagram might see millions of reads but only thousands of writes per second.&lt;/p&gt;

&lt;p&gt;CQRS answers: What if reads and writes were treated as separate concerns?&lt;/p&gt;

&lt;p&gt;Instead of one model for everything, CQRS introduces:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Write Model
     |
Read Model
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each side can be optimized independently.&lt;/p&gt;

&lt;h3&gt;
  
  
  CQRS thinks in commands and queries
&lt;/h3&gt;

&lt;p&gt;Core assumption: The way you update data is often different from the way you retrieve it.&lt;/p&gt;

&lt;p&gt;Example: Updating an order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Validate
Authorize
Apply Business Rules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Viewing an order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fetch
Format
Display
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These concerns do not necessarily belong in the same model.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Traditional CRUD&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Orders Table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Used for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'shipped'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CQRS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Write side:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ShipOrder Command
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read side:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OrderDetails Query
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two separate paths.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Command
   |
Write Model
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Query
   |
Read Model
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Independent read/write optimization&lt;/td&gt;
&lt;td&gt;Significantly more complexity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Better scalability&lt;/td&gt;
&lt;td&gt;Eventual consistency issues&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cleaner domain logic&lt;/td&gt;
&lt;td&gt;More infrastructure required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flexible read models&lt;/td&gt;
&lt;td&gt;Harder debugging&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Excellent for read-heavy systems&lt;/td&gt;
&lt;td&gt;More moving parts to maintain&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Natural fit for event-driven architectures&lt;/td&gt;
&lt;td&gt;Steeper learning curve&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Can improve performance dramatically&lt;/td&gt;
&lt;td&gt;Overkill for many applications&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use Webhooks when...
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;External systems need notifications&lt;/li&gt;
&lt;li&gt;Integration requirements are relatively simple&lt;/li&gt;
&lt;li&gt;You want the lowest operational overhead&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use EventBridge-style APIs when...
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Events must be distributed to multiple consumers&lt;/li&gt;
&lt;li&gt;Systems are highly decoupled&lt;/li&gt;
&lt;li&gt;Centralized event routing is valuable&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use Event Sourcing when...
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Event history is a business requirement&lt;/li&gt;
&lt;li&gt;Auditability and replayability matter&lt;/li&gt;
&lt;li&gt;State changes must be preserved permanently&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use CQRS when...
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Read and write workloads have different requirements&lt;/li&gt;
&lt;li&gt;Query performance becomes a concern&lt;/li&gt;
&lt;li&gt;Independent scaling of commands and queries is beneficial&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use Event Sourcing + CQRS when...
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Building complex event-driven systems&lt;/li&gt;
&lt;li&gt;Historical event storage and specialized read models are both required&lt;/li&gt;
&lt;li&gt;Additional architectural complexity is justified by business needs&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>webdev</category>
      <category>tutorial</category>
      <category>systemdesign</category>
      <category>api</category>
    </item>
    <item>
      <title>Messaging Systems: MQTT vs AMQP vs RabbitMQ vs Kafka vs NATS vs Apache Pulsar</title>
      <dc:creator>Shiv Rai (S_RAI)</dc:creator>
      <pubDate>Thu, 17 Sep 2026 13:50:50 +0000</pubDate>
      <link>https://dev.to/rai_shiv/messaging-systems-mqtt-vs-amqp-vs-rabbitmq-vs-kafka-vs-nats-vs-apache-pulsar-5elk</link>
      <guid>https://dev.to/rai_shiv/messaging-systems-mqtt-vs-amqp-vs-rabbitmq-vs-kafka-vs-nats-vs-apache-pulsar-5elk</guid>
      <description>&lt;h2&gt;
  
  
  What are messaging systems?
&lt;/h2&gt;

&lt;p&gt;Messaging systems enable applications to communicate by exchanging messages through shared infrastructure rather than communicating directly with each other.&lt;/p&gt;

&lt;p&gt;In direct communication models, a sender typically expects the receiver to be available and responsive at the time of the interaction. Messaging systems remove this dependency by introducing intermediaries that can receive, store, route, and deliver messages independently of the sender and receiver.&lt;/p&gt;

&lt;p&gt;This approach exists because distributed systems are inherently asynchronous. Services fail, networks become unreliable, workloads spike unexpectedly, and systems evolve independently. Messaging infrastructure helps absorb these realities by decoupling producers from consumers.&lt;/p&gt;

&lt;p&gt;Common building blocks include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Brokers&lt;/strong&gt; that receive, route, and deliver messages&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Queues&lt;/strong&gt; that distribute work among consumers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Topics&lt;/strong&gt; that publish messages to multiple subscribers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consumers&lt;/strong&gt; that process messages independently of producers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Common use cases include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Background job processing&lt;/li&gt;
&lt;li&gt;Microservice communication&lt;/li&gt;
&lt;li&gt;Event distribution&lt;/li&gt;
&lt;li&gt;Data pipelines&lt;/li&gt;
&lt;li&gt;IoT telemetry&lt;/li&gt;
&lt;li&gt;Workflow orchestration&lt;/li&gt;
&lt;li&gt;Stream processing&lt;/li&gt;
&lt;li&gt;System integration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article covers: MQTT, AMQP, RabbitMQ, Kafka, NATS, Apache Pulsar&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding the Technologies
&lt;/h3&gt;

&lt;p&gt;Not all technologies in this category solve the same problem or exist at the same architectural layer. Some define how messages are transmitted, while others provide the infrastructure that stores, routes, and delivers those messages.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Primary Focus&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MQTT&lt;/td&gt;
&lt;td&gt;Messaging Protocol&lt;/td&gt;
&lt;td&gt;Lightweight communication for constrained devices and unreliable networks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AMQP&lt;/td&gt;
&lt;td&gt;Messaging Protocol&lt;/td&gt;
&lt;td&gt;Standardized broker-based messaging and routing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RabbitMQ&lt;/td&gt;
&lt;td&gt;Message Broker&lt;/td&gt;
&lt;td&gt;Traditional queue-based messaging and work distribution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kafka&lt;/td&gt;
&lt;td&gt;Event Streaming Platform&lt;/td&gt;
&lt;td&gt;Durable event streams and large-scale data pipelines&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NATS&lt;/td&gt;
&lt;td&gt;Messaging System&lt;/td&gt;
&lt;td&gt;Lightweight, low-latency messaging and service communication&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apache Pulsar&lt;/td&gt;
&lt;td&gt;Messaging &amp;amp; Streaming Platform&lt;/td&gt;
&lt;td&gt;Unified messaging and event streaming infrastructure&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Some choices are complementary rather than competing.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MQTT messages are often transported through MQTT brokers.&lt;/li&gt;
&lt;li&gt;RabbitMQ commonly implements AMQP concepts and protocols — specifically the AMQP 0-9-1 dialect, not the later OASIS-standardized AMQP 1.0. AMQP is the protocol specification; RabbitMQ is one concrete, operable broker that implements it.&lt;/li&gt;
&lt;li&gt;Kafka and Pulsar are typically chosen for event-streaming workloads rather than traditional work queues.&lt;/li&gt;
&lt;li&gt;NATS focuses on lightweight messaging rather than long-term event storage.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Decision Tree
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;MQTT is typically chosen when devices operate on unreliable, low-bandwidth, or battery-constrained networks.&lt;/li&gt;
&lt;li&gt;AMQP is a protocol standard rather than a product you deploy directly; in practice, most teams get AMQP-style messaging by choosing RabbitMQ, which implements the widely-adopted AMQP 0-9-1 dialect.&lt;/li&gt;
&lt;li&gt;RabbitMQ is often the default choice for traditional queues, task distribution, and workflow orchestration.&lt;/li&gt;
&lt;li&gt;Kafka is most compelling when messages become long-lived streams of data that must be replayed and processed repeatedly.&lt;/li&gt;
&lt;li&gt;NATS is optimized for lightweight, low-latency service communication.&lt;/li&gt;
&lt;li&gt;Pulsar becomes attractive when both messaging and streaming capabilities are needed within the same distributed platform.
&lt;/li&gt;
&lt;/ul&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TD

A[Need Messaging Infrastructure] --&amp;gt; B{Communicating with&amp;lt;br/&amp;gt;devices over unreliable&amp;lt;br/&amp;gt;or constrained networks?}

B --&amp;gt;|Yes| MQTT[MQTT]

B --&amp;gt;|No| C{Need durable event streams,&amp;lt;br/&amp;gt;replay, and data pipelines?}

C --&amp;gt;|Yes| D{Need large-scale multi-tenancy,&amp;lt;br/&amp;gt;geo-distribution, or both messaging&amp;lt;br/&amp;gt;and streaming in one platform?}

D --&amp;gt;|Yes| PULSAR[Apache Pulsar]
D --&amp;gt;|No| KAFKA[Kafka]

C --&amp;gt;|No| E{Need traditional queues,&amp;lt;br/&amp;gt;routing, and work distribution?}

E --&amp;gt;|Yes| RABBIT[RabbitMQ&amp;lt;br/&amp;gt;implements AMQP 0-9-1]

E --&amp;gt;|No| G{Need lightweight,&amp;lt;br/&amp;gt;low-latency service messaging?}

G --&amp;gt;|Yes| NATS[NATS]
G --&amp;gt;|No| RABBIT&lt;/code&gt;&lt;/pre&gt;






&lt;h2&gt;
  
  
  Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;MQTT&lt;/th&gt;
&lt;th&gt;AMQP&lt;/th&gt;
&lt;th&gt;RabbitMQ&lt;/th&gt;
&lt;th&gt;Kafka&lt;/th&gt;
&lt;th&gt;NATS&lt;/th&gt;
&lt;th&gt;Apache Pulsar&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Category&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Protocol&lt;/td&gt;
&lt;td&gt;Protocol&lt;/td&gt;
&lt;td&gt;Broker Platform&lt;/td&gt;
&lt;td&gt;Event Streaming Platform&lt;/td&gt;
&lt;td&gt;Messaging System&lt;/td&gt;
&lt;td&gt;Messaging &amp;amp; Streaming Platform&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Primary Model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Pub/Sub messaging&lt;/td&gt;
&lt;td&gt;Broker-based messaging standard&lt;/td&gt;
&lt;td&gt;Queues and routing&lt;/td&gt;
&lt;td&gt;Distributed event log&lt;/td&gt;
&lt;td&gt;Lightweight messaging and pub/sub&lt;/td&gt;
&lt;td&gt;Unified messaging and streaming&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Messaging vs Streaming&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Messaging&lt;/td&gt;
&lt;td&gt;Messaging&lt;/td&gt;
&lt;td&gt;Messaging&lt;/td&gt;
&lt;td&gt;Streaming-first&lt;/td&gt;
&lt;td&gt;Messaging&lt;/td&gt;
&lt;td&gt;Messaging + Streaming&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Message Persistence&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;td&gt;Protocol-dependent&lt;/td&gt;
&lt;td&gt;Strong persistence support&lt;/td&gt;
&lt;td&gt;Core design principle&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;td&gt;Core design principle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Delivery Guarantees&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Configurable QoS levels&lt;/td&gt;
&lt;td&gt;Protocol-defined guarantees&lt;/td&gt;
&lt;td&gt;Strong acknowledgment model&lt;/td&gt;
&lt;td&gt;Strong durability and replay&lt;/td&gt;
&lt;td&gt;Configurable depending on deployment mode&lt;/td&gt;
&lt;td&gt;Strong durability and acknowledgment model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Throughput Profile&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Device-oriented workloads&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;Very high&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Very high&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Latency Profile&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;Low to moderate&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Very low&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scalability Model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Device fleets&lt;/td&gt;
&lt;td&gt;Broker-dependent&lt;/td&gt;
&lt;td&gt;Clustered broker scaling&lt;/td&gt;
&lt;td&gt;Distributed partitions&lt;/td&gt;
&lt;td&gt;Distributed messaging fabric&lt;/td&gt;
&lt;td&gt;Distributed storage and brokers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ordering Model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Limited and workload-dependent&lt;/td&gt;
&lt;td&gt;Implementation-dependent&lt;/td&gt;
&lt;td&gt;Queue ordering&lt;/td&gt;
&lt;td&gt;Partition ordering&lt;/td&gt;
&lt;td&gt;Subject ordering&lt;/td&gt;
&lt;td&gt;Partition ordering&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Operational Complexity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Varies by implementation&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ecosystem Maturity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Mature&lt;/td&gt;
&lt;td&gt;Mature standard&lt;/td&gt;
&lt;td&gt;Very mature&lt;/td&gt;
&lt;td&gt;Very mature&lt;/td&gt;
&lt;td&gt;Mature&lt;/td&gt;
&lt;td&gt;Mature&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Typical Use Cases&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;IoT, telemetry, edge devices&lt;/td&gt;
&lt;td&gt;Enterprise interoperability&lt;/td&gt;
&lt;td&gt;Background jobs, workflows, task queues&lt;/td&gt;
&lt;td&gt;Event streaming, analytics, CDC, data platforms&lt;/td&gt;
&lt;td&gt;Service communication, cloud-native systems&lt;/td&gt;
&lt;td&gt;Multi-tenant platforms, messaging and streaming&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Strengths&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Efficient on constrained networks&lt;/td&gt;
&lt;td&gt;Standardized interoperability&lt;/td&gt;
&lt;td&gt;Mature queueing and routing model&lt;/td&gt;
&lt;td&gt;Replayability, durability, ecosystem, scale&lt;/td&gt;
&lt;td&gt;Simplicity, speed, low operational overhead&lt;/td&gt;
&lt;td&gt;Combines queueing and streaming capabilities&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Weaknesses&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Not intended for large-scale stream processing&lt;/td&gt;
&lt;td&gt;Requires a broker implementation&lt;/td&gt;
&lt;td&gt;Less suited for event-streaming workloads&lt;/td&gt;
&lt;td&gt;More complex than traditional messaging systems&lt;/td&gt;
&lt;td&gt;Not designed as a long-term event log&lt;/td&gt;
&lt;td&gt;More operationally complex than simpler alternatives&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Messaging vs Streaming
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;If you need...&lt;/th&gt;
&lt;th&gt;Usually Start With&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Background jobs and work queues&lt;/td&gt;
&lt;td&gt;RabbitMQ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Task distribution&lt;/td&gt;
&lt;td&gt;RabbitMQ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enterprise broker-based messaging&lt;/td&gt;
&lt;td&gt;RabbitMQ / AMQP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Device communication&lt;/td&gt;
&lt;td&gt;MQTT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Service-to-service messaging with minimal latency&lt;/td&gt;
&lt;td&gt;NATS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Durable event streams and replay&lt;/td&gt;
&lt;td&gt;Kafka&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unified messaging and streaming&lt;/td&gt;
&lt;td&gt;Pulsar&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;If messages are consumed once and discarded -&amp;gt; Messaging&lt;/li&gt;
&lt;li&gt;If messages become a durable history that multiple consumers may replay-&amp;gt; streaming&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  MQTT
&lt;/h1&gt;

&lt;p&gt;MQTT (Message Queuing Telemetry Transport) was created in 1999. At the time, many devices operated under severe constraints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Oil Pipeline Sensors&lt;/li&gt;
&lt;li&gt;Satellite Links&lt;/li&gt;
&lt;li&gt;Industrial Equipment&lt;/li&gt;
&lt;li&gt;Remote Monitoring Systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These environments often had:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;High latency&lt;/li&gt;
&lt;li&gt;Expensive bandwidth&lt;/li&gt;
&lt;li&gt;Intermittent connectivity&lt;/li&gt;
&lt;li&gt;Low-power hardware&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;HTTP was considered too heavy. The goal of MQTT was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Minimal Bandwidth&lt;/li&gt;
&lt;li&gt;Minimal Power Usage&lt;/li&gt;
&lt;li&gt;Minimal Complexity&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  MQTT thinks in topics and subscriptions
&lt;/h3&gt;

&lt;p&gt;The model breaks down into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Publishers&lt;/li&gt;
&lt;li&gt;Topics&lt;/li&gt;
&lt;li&gt;Subscribers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Device A ---&amp;gt; Device B
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Device A
    |
 Publish
    |
temperature/room1
    |
 MQTT Broker
    |
 Subscribe
    |
Device B
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Publisher&lt;/strong&gt;&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;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;temperature/room1&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;24.5&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;&lt;strong&gt;Subscriber&lt;/strong&gt;&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;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;temperature/room1&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;Whenever a message arrives:&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="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;msg&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;24.5
25.1
24.8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Quality of Service (QoS)
&lt;/h3&gt;

&lt;p&gt;MQTT lets each subscription choose its own delivery guarantee:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;QoS 0&lt;/strong&gt; – at most once (fire and forget)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;QoS 1&lt;/strong&gt; – at least once (may deliver duplicates)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;QoS 2&lt;/strong&gt; – exactly once (highest overhead)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Constrained devices often default to QoS 0 or 1 to save bandwidth and battery, reserving QoS 2 for messages that can't tolerate loss or duplication.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Extremely lightweight&lt;/td&gt;
&lt;td&gt;Requires broker infrastructure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Excellent for IoT&lt;/td&gt;
&lt;td&gt;Poor fit for request/response APIs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Low bandwidth usage&lt;/td&gt;
&lt;td&gt;Topic design can become complex&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supports unreliable networks&lt;/td&gt;
&lt;td&gt;Harder to debug than HTTP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;QoS delivery guarantees&lt;/td&gt;
&lt;td&gt;Security must be carefully managed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Publisher/subscriber decoupling&lt;/td&gt;
&lt;td&gt;Not ideal for CRUD applications&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Huge industry adoption&lt;/td&gt;
&lt;td&gt;Less suitable for large analytics pipelines&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h1&gt;
  
  
  AMQP
&lt;/h1&gt;

&lt;p&gt;AMQP (Advanced Message Queuing Protocol) was first developed around 2003–2006. A stable specification shipped in 2008, with formal standardization through OASIS following in 2012. Large enterprises were building systems that relied heavily on messaging:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Banking&lt;/li&gt;
&lt;li&gt;Trading&lt;/li&gt;
&lt;li&gt;Payments&lt;/li&gt;
&lt;li&gt;Order Processing&lt;/li&gt;
&lt;li&gt;Enterprise Integration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every vendor had its own protocol which often couldn't communicate with each other. AMQP aimed to create a standard protocol for reliable enterprise messaging.&lt;/p&gt;

&lt;p&gt;The goal was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Guaranteed Delivery&lt;/li&gt;
&lt;li&gt;Reliable Routing&lt;/li&gt;
&lt;li&gt;Transactions&lt;/li&gt;
&lt;li&gt;Interoperability&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AMQP thinks in a standardized routing model
&lt;/h3&gt;

&lt;p&gt;Core assumption: &lt;strong&gt;Routing behavior should be defined by the protocol itself, not by whichever broker happens to run it&lt;/strong&gt; — so producers, consumers, and brokers from different vendors can all agree on the same messaging semantics.&lt;/p&gt;

&lt;p&gt;This is a different mental model from "call a specific broker's API." AMQP is a wire-level specification: it describes exchanges, bindings, and queues as protocol concepts that any compliant broker must implement the same way.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Messages
+
Routing Rules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Producer&lt;/strong&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="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;basic_publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;exchange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;orders&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;routing_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;created&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Order #123&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Consumer&lt;/strong&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="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;basic_consume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;order-service&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Producer sends:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Order #123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Consumer receives:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Order #123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exchanges and Routing
&lt;/h3&gt;

&lt;p&gt;AMQP's "sophisticated" routing comes from &lt;strong&gt;exchanges&lt;/strong&gt; sitting between producers and queues. A producer publishes to an exchange, not directly to a queue, and the exchange decides where the message goes based on its type:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Direct&lt;/strong&gt; – routes by exact routing-key match&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Topic&lt;/strong&gt; – routes by pattern match (e.g., &lt;code&gt;orders.*&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fanout&lt;/strong&gt; – broadcasts to every bound queue&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Headers&lt;/strong&gt; – routes based on message header values&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is what lets a single published message reach multiple queues, or be filtered before it ever reaches a consumer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Very reliable delivery&lt;/td&gt;
&lt;td&gt;More complex than MQTT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Powerful routing via exchanges&lt;/td&gt;
&lt;td&gt;Higher operational overhead&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Durable queues and acknowledgements&lt;/td&gt;
&lt;td&gt;Heavier protocol footprint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supports many messaging patterns&lt;/td&gt;
&lt;td&gt;Not ideal for large event streams&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mature RabbitMQ ecosystem&lt;/td&gt;
&lt;td&gt;Infrastructure can become complex&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strong enterprise adoption&lt;/td&gt;
&lt;td&gt;Less suitable for constrained devices&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Good for workflows and background jobs&lt;/td&gt;
&lt;td&gt;Overkill for simple applications&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h1&gt;
  
  
  Kafka
&lt;/h1&gt;

&lt;p&gt;Apache Kafka was created at LinkedIn around 2010 and open-sourced in 2011. LinkedIn's infrastructure was generating massive amounts of events:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Page Views
Clicks
User Activity
Logs
Metrics
Analytics
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Different systems needed access to the same data. This created tight coupling and scalability problems. Kafka was designed to answer, "How can thousands of systems continuously produce and consume events at massive scale?" The goal was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Store Events&lt;/li&gt;
&lt;li&gt;Replay Events&lt;/li&gt;
&lt;li&gt;Process Events&lt;/li&gt;
&lt;li&gt;Scale Horizontally&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Kafka is not primarily a message queue.&lt;/p&gt;

&lt;p&gt;Kafka is an event streaming platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  Kafka thinks in event logs
&lt;/h3&gt;

&lt;p&gt;Kafka's model centers on immutable event streams.&lt;/p&gt;

&lt;p&gt;Core assumption: Events are valuable records that should be stored, not merely delivered.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Producer
   |
Queue
   |
Consumer
   |
Delete Message
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kafka's approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Producer
   |
Append Event
   |
Log
   |
Consumer Reads
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The event remains in the log.&lt;/p&gt;

&lt;p&gt;This is the most important concept in Kafka.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Producer&lt;/strong&gt;&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="err"&gt;producer.send(&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"orders"&lt;/span&gt;&lt;span class="err"&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;"orderId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"created"&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="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Consumer&lt;/strong&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&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;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&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;"orderId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"created"&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;The key difference: The event remains stored even after consumption. Another consumer can read it later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Partitions and Consumer Groups
&lt;/h3&gt;

&lt;p&gt;A Kafka topic is split into &lt;strong&gt;partitions&lt;/strong&gt;, each an ordered, append-only log. Partitioning is what lets Kafka scale horizontally — different partitions can live on different brokers and be written and read in parallel.&lt;/p&gt;

&lt;p&gt;Consumers read partitions in &lt;strong&gt;consumer groups&lt;/strong&gt;: Kafka assigns each partition to exactly one consumer within a group, so the group as a whole processes a topic in parallel while each individual partition stays strictly ordered.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Massive throughput&lt;/td&gt;
&lt;td&gt;Operational complexity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Event replay capability&lt;/td&gt;
&lt;td&gt;Higher resource requirements&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Durable event storage&lt;/td&gt;
&lt;td&gt;Not suited for RPC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Excellent scalability&lt;/td&gt;
&lt;td&gt;Event schema management can be difficult&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Decouples producers and consumers&lt;/td&gt;
&lt;td&gt;Eventual consistency challenges&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strong ecosystem and tooling&lt;/td&gt;
&lt;td&gt;Can be overkill for small systems&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ideal for analytics and event-driven systems&lt;/td&gt;
&lt;td&gt;Steeper learning curve&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h1&gt;
  
  
  NATS
&lt;/h1&gt;

&lt;p&gt;NATS was created by Derek Collison and first released around 2011. Around the early 2010s, distributed systems (Microservices, Containers, Cloud Platforms, Service Meshes) were becoming increasingly common. Existing messaging systems often fell into two categories:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;RabbitMQ → Feature Rich&lt;/li&gt;
&lt;li&gt;Kafka → Massive Scale&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But many teams wanted:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Simple
Fast
Reliable
Cloud Native
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;without operating a large messaging platform.&lt;/p&gt;

&lt;p&gt;NATS was designed to answer: What's the simplest possible way for distributed services to communicate?&lt;/p&gt;

&lt;p&gt;The philosophy was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Small Protocol
Small Server
Low Latency
High Simplicity
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  NATS thinks in subjects
&lt;/h3&gt;

&lt;p&gt;Core assumption: Services should communicate through lightweight, hierarchical subjects rather than pre-declared queues or topics.&lt;/p&gt;

&lt;p&gt;Subjects are just dot-separated strings, and wildcards let a subscriber match many subjects at once without the publisher and subscriber agreeing on a fixed topic list in advance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="err"&gt;orders.created&lt;/span&gt;     &lt;span class="c"&gt;# exact subject
&lt;/span&gt;&lt;span class="err"&gt;orders.*&lt;/span&gt;           &lt;span class="c"&gt;# matches orders.created, orders.cancelled, etc.
&lt;/span&gt;&lt;span class="err"&gt;orders.&amp;gt;&lt;/span&gt;           &lt;span class="c"&gt;# matches orders.created, orders.us.created, and deeper
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Publisher&lt;/strong&gt;&lt;br&gt;
&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;nc&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;"orders.created"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"123"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Subscriber&lt;/strong&gt;&lt;br&gt;
&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;nc&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="s"&gt;"orders.created"&lt;/span&gt;&lt;span class="p"&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;msg&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;nats&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Msg&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="kt"&gt;string&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;Data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  JetStream
&lt;/h3&gt;

&lt;p&gt;By default, core NATS messages are fire-and-forget — if no one is subscribed when a message is published, it's gone. &lt;strong&gt;JetStream&lt;/strong&gt; is NATS's built-in persistence layer: it adds durable storage, message replay, and at-least-once delivery on top of core NATS subjects. It's what lets NATS take on some Kafka-like use cases, at the cost of some of the operational simplicity that makes core NATS attractive in the first place.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Extremely low latency&lt;/td&gt;
&lt;td&gt;Smaller ecosystem&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Operationally simple&lt;/td&gt;
&lt;td&gt;Less suited for analytics workloads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lightweight deployment&lt;/td&gt;
&lt;td&gt;JetStream increases complexity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Excellent for microservices&lt;/td&gt;
&lt;td&gt;Fewer integrations than Kafka&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supports pub/sub and RPC&lt;/td&gt;
&lt;td&gt;Smaller talent pool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloud-native friendly&lt;/td&gt;
&lt;td&gt;Not ideal for long-term event storage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Easier to run than Kafka/RabbitMQ&lt;/td&gt;
&lt;td&gt;Less proven for huge data platforms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h1&gt;
  
  
  Apache Pulsar
&lt;/h1&gt;

&lt;p&gt;Apache Pulsar was originally developed at Yahoo around 2013 and open-sourced in 2016. Yahoo operated some of the world's largest messaging and data systems:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Mail
News
Advertising
Search
Analytics
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At that scale, traditional messaging systems began showing limitations. Particularly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Storage Scaling
Broker Scaling
Multi-Tenancy
Geo Replication
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kafka was already successful, but Yahoo wanted a different architecture. Most messaging platforms looked like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Broker
  |
Storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pulsar introduced:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Broker
  |
Storage Layer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;as separate components.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pulsar thinks in event streams with separated compute and storage
&lt;/h3&gt;

&lt;p&gt;Core assumption: Messaging and storage should scale independently.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Broker
  |
Stores Data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pulsar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Broker
  |
Reads/Writes
  |
Storage System
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates more flexibility at scale. In practice, it means brokers can be added or removed to handle more traffic without touching how data is stored, and storage capacity can grow independently to hold more history — something a coupled broker-and-storage design can't do without rebalancing both at once.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Producer&lt;/strong&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;Producer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;producer&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="na"&gt;newProducer&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;topic&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"orders"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;producer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"Order Created"&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Consumer&lt;/strong&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;Consumer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;consumer&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="na"&gt;newConsumer&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;topic&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"orders"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;subscriptionName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"billing"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;subscribe&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Receive:&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;Message&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;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;consumer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;receive&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks very similar to Kafka but architecturally different.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Independent compute and storage scaling&lt;/td&gt;
&lt;td&gt;More complex architecture&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Built-in multi-tenancy&lt;/td&gt;
&lt;td&gt;Smaller ecosystem&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Native geo-replication&lt;/td&gt;
&lt;td&gt;Fewer experienced operators&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supports queues, streams, and pub/sub&lt;/td&gt;
&lt;td&gt;More moving parts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Durable storage via BookKeeper&lt;/td&gt;
&lt;td&gt;Higher operational complexity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strong cloud-native support&lt;/td&gt;
&lt;td&gt;Kafka tooling ecosystem is larger&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Excellent for large organizations&lt;/td&gt;
&lt;td&gt;Often overkill for smaller systems&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h1&gt;
  
  
  RabbitMQ
&lt;/h1&gt;

&lt;p&gt;RabbitMQ was first released in 2007 by Rabbit Technologies and is one of the most widely adopted implementations of AMQP. Specifically, RabbitMQ is built around AMQP 0-9-1, an earlier and more widely deployed dialect than the later OASIS-standardized AMQP 1.0 — this is why RabbitMQ isn't automatically wire-compatible with every "AMQP" broker.&lt;/p&gt;

&lt;p&gt;Before RabbitMQ, many applications communicated directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Service A
    |
Service B
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This created problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tight Coupling&lt;/li&gt;
&lt;li&gt;Retries&lt;/li&gt;
&lt;li&gt;Downtime Propagation&lt;/li&gt;
&lt;li&gt;Traffic Spikes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Teams wanted a reliable middle layer that could:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Store Messages&lt;/li&gt;
&lt;li&gt;Route Messages&lt;/li&gt;
&lt;li&gt;Retry Delivery&lt;/li&gt;
&lt;li&gt;Guarantee Processing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;RabbitMQ answers: How can services exchange messages reliably without needing to be online at the same time?&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Producer
    |
Consumer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Producer
    |
RabbitMQ
    |
Consumer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The broker acts as a buffer and router.&lt;/p&gt;

&lt;h3&gt;
  
  
  RabbitMQ thinks in exchanges you actually operate
&lt;/h3&gt;

&lt;p&gt;Core assumption: The abstract routing model AMQP describes needs a real, operable broker behind it — with clustering, a management UI, plugins, and tuning knobs. RabbitMQ is that broker: it implements AMQP's exchange-and-queue routing model and adds its own operational tooling, protocol plugins (including MQTT and STOMP support), and ecosystem on top.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OrderCreated
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Producer sends the message.&lt;/p&gt;

&lt;p&gt;RabbitMQ decides:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Email Service
Analytics Service
Inventory Service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;should receive it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Producer&lt;/strong&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="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;basic_publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;exchange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;orders&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;routing_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;created&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Order #123&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Consumer&lt;/strong&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="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;basic_consume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;email-service&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;on_message_callback&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;handler&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Order #123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;flows through RabbitMQ.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Mature and battle-tested&lt;/td&gt;
&lt;td&gt;More complex than NATS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Powerful routing via exchanges&lt;/td&gt;
&lt;td&gt;Not optimized for event streaming&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strong reliability guarantees&lt;/td&gt;
&lt;td&gt;Scaling can become complex&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Excellent worker queue support&lt;/td&gt;
&lt;td&gt;Lower throughput than Kafka&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Durable queues and retries&lt;/td&gt;
&lt;td&gt;Ordering can be difficult at scale&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Large ecosystem and tooling&lt;/td&gt;
&lt;td&gt;More operational overhead&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supports multiple messaging patterns&lt;/td&gt;
&lt;td&gt;Not ideal for long-term event retention&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  Key Takeaway
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Choose &lt;strong&gt;MQTT&lt;/strong&gt; for device communication.&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;RabbitMQ&lt;/strong&gt; (the practical way to get &lt;strong&gt;AMQP&lt;/strong&gt;-style messaging) for traditional messaging and queues.&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;NATS&lt;/strong&gt; for lightweight, low-latency messaging.&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;Kafka&lt;/strong&gt; for durable event streams and data platforms.&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;Pulsar&lt;/strong&gt; when messaging and streaming must coexist within the same platform.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>tutorial</category>
      <category>systemdesign</category>
      <category>api</category>
    </item>
    <item>
      <title>Real Time Communication: SSE vs WebSockets vs WebRTC</title>
      <dc:creator>Shiv Rai (S_RAI)</dc:creator>
      <pubDate>Wed, 16 Sep 2026 11:27:20 +0000</pubDate>
      <link>https://dev.to/rai_shiv/real-time-communication-sse-vs-websockets-vs-webrtc-4alb</link>
      <guid>https://dev.to/rai_shiv/real-time-communication-sse-vs-websockets-vs-webrtc-4alb</guid>
      <description>&lt;h2&gt;
  
  
  Real Time communication
&lt;/h2&gt;

&lt;p&gt;Real-time communication enables systems to deliver updates as soon as information changes, rather than waiting for clients to ask for new data.&lt;/p&gt;

&lt;p&gt;In traditional request/response architectures, a client initiates every interaction. If new information is needed, the client must send another request. Real-time systems invert this pattern by allowing servers to push updates whenever events occur.&lt;/p&gt;

&lt;p&gt;Many applications need information immediately. Waiting for users to refresh a page or repeatedly poll an API introduces unnecessary latency, wasted network traffic, and a poorer user experience.&lt;/p&gt;

&lt;p&gt;Common use cases include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chat and messaging applications&lt;/li&gt;
&lt;li&gt;Live dashboards and monitoring systems&lt;/li&gt;
&lt;li&gt;Notifications and alerts&lt;/li&gt;
&lt;li&gt;Financial market feeds&lt;/li&gt;
&lt;li&gt;Collaborative editing tools&lt;/li&gt;
&lt;li&gt;Multiplayer games&lt;/li&gt;
&lt;li&gt;Live tracking and telemetry systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The core idea is: instead of repeatedly requesting new information, clients subscribe to a stream of events, exchange messages continuously, or connect directly to another peer, and receive updates as they happen.&lt;/p&gt;

&lt;p&gt;This article covers: SSE, WebSockets, WebRTC.&lt;/p&gt;




&lt;h2&gt;
  
  
  Decision Tree
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Server pushes updates and clients mainly consume them -&amp;gt; SSE&lt;/li&gt;
&lt;li&gt;Both sides need to exchange information continuously through the server -&amp;gt; WebSockets&lt;/li&gt;
&lt;li&gt;Communication happens directly between peers, especially for voice, video, or low-latency data transfer -&amp;gt; WebRTC
&lt;/li&gt;
&lt;/ul&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TD

A[Need Real-Time Communication] --&amp;gt; B{Does communication happen&amp;lt;br/&amp;gt;directly between peers rather&amp;lt;br/&amp;gt;than through your server?}

B --&amp;gt;|Yes| C{Building voice/video, or need&amp;lt;br/&amp;gt;low-latency peer-to-peer&amp;lt;br/&amp;gt;data transfer?}

C --&amp;gt;|Yes| WEBRTC[WebRTC]

B --&amp;gt;|No| D{Do clients need to send&amp;lt;br/&amp;gt;real-time messages back&amp;lt;br/&amp;gt;to the server?}

D --&amp;gt;|Yes| WS[WebSockets]

D --&amp;gt;|No| SSE[SSE]&lt;/code&gt;&lt;/pre&gt;






&lt;h2&gt;
  
  
  Comparison.
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;WebSockets&lt;/th&gt;
&lt;th&gt;Server-Sent Events (SSE)&lt;/th&gt;
&lt;th&gt;WebRTC&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Mental Model&lt;/td&gt;
&lt;td&gt;Persistent conversation between client and server&lt;/td&gt;
&lt;td&gt;Continuous stream of server-generated events&lt;/td&gt;
&lt;td&gt;Direct peer-to-peer channel for media and data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Communication Direction&lt;/td&gt;
&lt;td&gt;Bidirectional&lt;/td&gt;
&lt;td&gt;Server → Client only&lt;/td&gt;
&lt;td&gt;Bidirectional, directly between peers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Connection Type&lt;/td&gt;
&lt;td&gt;Persistent full-duplex connection&lt;/td&gt;
&lt;td&gt;Persistent HTTP response stream&lt;/td&gt;
&lt;td&gt;Direct peer-to-peer connection, established with signaling assistance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Browser Support&lt;/td&gt;
&lt;td&gt;Excellent in modern browsers&lt;/td&gt;
&lt;td&gt;Excellent in modern browsers&lt;/td&gt;
&lt;td&gt;Excellent in modern browsers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complexity&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scalability Considerations&lt;/td&gt;
&lt;td&gt;Requires managing stateful bidirectional connections&lt;/td&gt;
&lt;td&gt;Typically simpler infrastructure and scaling model&lt;/td&gt;
&lt;td&gt;Scales well 1:1; group communication needs additional infrastructure (SFU/MCU)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Latency&lt;/td&gt;
&lt;td&gt;Very low&lt;/td&gt;
&lt;td&gt;Very low&lt;/td&gt;
&lt;td&gt;Very low once a direct connection is established&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reconnection Behavior&lt;/td&gt;
&lt;td&gt;Usually implemented by application or framework&lt;/td&gt;
&lt;td&gt;Built-in automatic reconnection support&lt;/td&gt;
&lt;td&gt;Requires handling ICE restarts and renegotiation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Typical Use Cases&lt;/td&gt;
&lt;td&gt;Chat, collaboration, multiplayer systems, interactive applications&lt;/td&gt;
&lt;td&gt;Notifications, dashboards, monitoring, live feeds, status updates&lt;/td&gt;
&lt;td&gt;Video calls, voice calls, screen sharing, peer-to-peer file transfer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strengths&lt;/td&gt;
&lt;td&gt;Full-duplex communication, highly flexible, supports interactive workloads&lt;/td&gt;
&lt;td&gt;Simple implementation, HTTP-friendly, automatic reconnection, efficient for broadcasts&lt;/td&gt;
&lt;td&gt;Lowest latency for direct exchange, reduces server bandwidth, native media support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Weaknesses&lt;/td&gt;
&lt;td&gt;More operational complexity and connection management&lt;/td&gt;
&lt;td&gt;No native client-to-server real-time channel&lt;/td&gt;
&lt;td&gt;Requires signaling, STUN/TURN infrastructure, and NAT traversal handling&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  WebSockets
&lt;/h2&gt;

&lt;p&gt;The web followed a simple model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser → Request
Server  → Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This worked well for websites but became problematic for real-time applications.&lt;/p&gt;

&lt;p&gt;Developers had to use techniques like Polling, Long Polling, Comet, and Hidden iframes to simulate real-time communication. These approaches were inefficient because browsers repeatedly asked, "Do you have new data yet?"&lt;/p&gt;

&lt;p&gt;WebSockets became an official web standard in 2011 through RFC 6455 and introduced a persistent, full-duplex connection between client and server.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client -&amp;gt; Request
Server -&amp;gt; Response
Connection Closed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebSocket provides:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client &amp;lt;=================&amp;gt; Server
         Always Open
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Either side can send data at any time.&lt;/p&gt;

&lt;h3&gt;
  
  
  WebSockets thinks in conversations
&lt;/h3&gt;

&lt;p&gt;WebSocket is for opening a connection and keeping it open. Once a connection has been established, both sides can continuously exchange messages. Core assumption: The application benefits from a long-lived connection where updates should be delivered immediately.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Client&lt;/strong&gt;&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;const&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WebSocket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ws://localhost:8080&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&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;&lt;strong&gt;Server (Node.js)&lt;/strong&gt;&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;wss&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="s2"&gt;connection&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;socket&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;socket&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="s2"&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;msg&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;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`received: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;msg&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="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Communication:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client -&amp;gt; hello
Server -&amp;gt; received: hello
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No new HTTP request is required.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Network compatibility note:&lt;/strong&gt; Some restrictive corporate networks, proxies, firewalls, or legacy infrastructure can interfere with WebSocket connections. This is one reason some teams prefer SSE or fallback solutions in environments where connectivity is less predictable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;True real-time communication&lt;/td&gt;
&lt;td&gt;Stateful connections&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Full duplex messaging&lt;/td&gt;
&lt;td&gt;More difficult to scale&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Low latency&lt;/td&gt;
&lt;td&gt;No built-in durability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Efficient for frequent updates&lt;/td&gt;
&lt;td&gt;Harder debugging and observability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Native browser support&lt;/td&gt;
&lt;td&gt;Cannot leverage HTTP caching&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reduces polling overhead&lt;/td&gt;
&lt;td&gt;Requires connection management&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Excellent for interactive applications&lt;/td&gt;
&lt;td&gt;Not ideal for CRUD APIs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Server-Sent Events (SSE)
&lt;/h2&gt;

&lt;p&gt;Server-Sent Events (SSE) were introduced as part of the HTML5 specification effort, with early browser implementations appearing around 2009–2011 and the standard later reaching W3C Recommendation status. Before SSE, web applications wanting real-time updates typically used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Polling&lt;/li&gt;
&lt;li&gt;Long Polling&lt;/li&gt;
&lt;li&gt;Hidden iframes&lt;/li&gt;
&lt;li&gt;Custom Hacks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A common pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser
   |
GET /notifications
   |
No updates
   |
Wait 5 seconds
   |
GET /notifications
   |
Repeat forever
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This wasted:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Network bandwidth&lt;/li&gt;
&lt;li&gt;Server resources&lt;/li&gt;
&lt;li&gt;Client resources&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Developers needed a standardized way for servers to push updates to browsers. SSE introduced one-way real-time communication from server to client over standard HTTP.&lt;/p&gt;

&lt;p&gt;Instead of constantly asking for updates, the browser opens a connection and the server sends updates whenever they occur.&lt;/p&gt;

&lt;h3&gt;
  
  
  SSE thinks in event streams
&lt;/h3&gt;

&lt;p&gt;Core assumption: The client mostly listens.&lt;/p&gt;

&lt;p&gt;Communication looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server
   |
Events
   |
Browser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser &amp;lt;-&amp;gt; Server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SSE is fundamentally one-way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Server&lt;/strong&gt;&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;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/events&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;req&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="o"&gt;=&amp;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="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&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;text/event-stream&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;setInterval&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="s2"&gt;`data: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;\n\n`&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Browser&lt;/strong&gt;&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;const&lt;/span&gt; &lt;span class="nx"&gt;events&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;EventSource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/events&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;events&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&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;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1726151231
1726151232
1726151233
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser receives updates automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Extremely simple API&lt;/td&gt;
&lt;td&gt;One-way only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Native browser support&lt;/td&gt;
&lt;td&gt;Not ideal for interactive apps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Automatic reconnection&lt;/td&gt;
&lt;td&gt;Limited binary support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uses standard HTTP&lt;/td&gt;
&lt;td&gt;Browser-oriented design&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Efficient for notifications&lt;/td&gt;
&lt;td&gt;Connection limits may apply&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Easy to debug&lt;/td&gt;
&lt;td&gt;Less flexible than WebSockets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Excellent for streaming updates&lt;/td&gt;
&lt;td&gt;Requires separate channel for client-to-server communication&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  WebRTC
&lt;/h2&gt;

&lt;p&gt;Before WebRTC, real-time voice and video in the browser required proprietary plugins like Flash, Skype's browser plugin, or similar. There was no native way for two browsers to establish a direct connection and exchange audio, video, or data without routing everything through a server.&lt;/p&gt;

&lt;p&gt;Google open-sourced WebRTC in 2011, aiming to bring peer-to-peer voice, video, and data communication natively into the browser, without plugins. &lt;/p&gt;

&lt;p&gt;WebRTC is now the default technology behind most browser-based video calling, voice calling, and screen-sharing products, and is also used for peer-to-peer data transfer and some multiplayer game architectures.&lt;/p&gt;

&lt;h3&gt;
  
  
  WebRTC thinks in peers
&lt;/h3&gt;

&lt;p&gt;WebRTC is about connecting two peers directly, so media and data can flow between them without passing through an application server.&lt;/p&gt;

&lt;p&gt;Core assumption: once two peers are connected, they exchange real-time media or data directly, with a server only needed to help establish that connection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Peer A&lt;/strong&gt;&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;const&lt;/span&gt; &lt;span class="nx"&gt;peer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RTCPeerConnection&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;channel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;peer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createDataChannel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;chat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onopen&lt;/span&gt; &lt;span class="o"&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;channel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&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;&lt;strong&gt;Peer B&lt;/strong&gt;&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;peer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ondatachannel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&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="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&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;Communication:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Peer A -&amp;gt; hello
Peer B -&amp;gt; received directly, no server relay
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lowest latency for direct peer communication&lt;/td&gt;
&lt;td&gt;Significantly more complex to implement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Native audio, video, and data channel support&lt;/td&gt;
&lt;td&gt;Requires a signaling mechanism, which WebRTC itself doesn't provide&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reduces server bandwidth costs by avoiding relay&lt;/td&gt;
&lt;td&gt;NAT traversal often requires STUN/TURN servers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;True peer-to-peer data exchange&lt;/td&gt;
&lt;td&gt;Group communication needs additional infrastructure (SFU/MCU)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Configurable reliable or unreliable data channels&lt;/td&gt;
&lt;td&gt;Harder to debug than client-server protocols&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Excellent for real-time media applications&lt;/td&gt;
&lt;td&gt;Connection setup involves multiple negotiation steps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Works directly in modern browsers without plugins&lt;/td&gt;
&lt;td&gt;Behavior can be less predictable across restrictive networks&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  A Note on Delivery Guarantees
&lt;/h2&gt;

&lt;p&gt;Neither SSE nor WebSockets guarantee message delivery while a client is disconnected — messages sent during an outage or a reconnect window can simply be missed. Systems that require durable delivery, replay, or guaranteed-once semantics typically reach for messaging platforms such as Kafka, NATS, RabbitMQ, or Pulsar instead of (or alongside) a real-time transport layer.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Choose SSE&lt;/strong&gt; when you need simple, one-way updates from server to client like: dashboards, notifications, and live feeds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Choose WebSockets&lt;/strong&gt; when both sides need to exchange information continuously through your server. Examples: Chat systems, collaborative applications, and multiplayer applications typically need this.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Choose WebRTC&lt;/strong&gt; when communication should happen directly between peers like voice calls, video calls, screen sharing, or low-latency peer-to-peer data transfer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Choose polling&lt;/strong&gt; when updates are infrequent and simplicity or operational ease matters more than immediate delivery.&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>webdev</category>
      <category>api</category>
      <category>tutorial</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>RPC Systems: JSON-RPC vs XML-RPC vs SOAP vs gRPC vs Apache Thrift vs Connect vs tRPC</title>
      <dc:creator>Shiv Rai (S_RAI)</dc:creator>
      <pubDate>Tue, 15 Sep 2026 12:39:45 +0000</pubDate>
      <link>https://dev.to/rai_shiv/rpc-systems-json-rpc-vs-xml-rpc-vs-soap-vs-grpc-vs-apache-thrift-vs-connect-vs-trpc-4n2e</link>
      <guid>https://dev.to/rai_shiv/rpc-systems-json-rpc-vs-xml-rpc-vs-soap-vs-grpc-vs-apache-thrift-vs-connect-vs-trpc-4n2e</guid>
      <description>&lt;h2&gt;
  
  
  What are RPCs?
&lt;/h2&gt;

&lt;p&gt;RPC (Remote Procedure Call) systems allow software running in one process, machine, or service to invoke functionality located somewhere else as if it were a local function call.&lt;/p&gt;

&lt;p&gt;The core idea behind RPC is abstraction. Instead of thinking in terms of resources, endpoints, or data representations, developers think in terms of calling procedures, methods, or functions. The networking details are handled by the RPC framework.&lt;/p&gt;

&lt;p&gt;In RPC interaction:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A client calls a remote method.&lt;/li&gt;
&lt;li&gt;The request is serialized and transmitted over the network.&lt;/li&gt;
&lt;li&gt;The remote service executes the procedure.&lt;/li&gt;
&lt;li&gt;The result is returned to the caller.&lt;/li&gt;
&lt;li&gt;The framework deserializes the response into native language objects.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;RPC systems exist because many distributed systems are fundamentally action-oriented rather than resource-oriented. They provide a natural way to model service-to-service communication, business operations, workflows, and internal platform APIs.&lt;/p&gt;

&lt;p&gt;Common use cases include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Microservice communication&lt;/li&gt;
&lt;li&gt;Internal platform APIs&lt;/li&gt;
&lt;li&gt;Backend-to-backend communication&lt;/li&gt;
&lt;li&gt;Distributed systems&lt;/li&gt;
&lt;li&gt;Enterprise integrations&lt;/li&gt;
&lt;li&gt;High-performance service meshes&lt;/li&gt;
&lt;li&gt;Full-stack TypeScript applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article includes: XML-RPC, SOAP, JSON-RPC, gRPC, Apache Thrift, Connect, tRPC&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Choose ?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Full-stack TypeScript development -&amp;gt; tRPC&lt;/li&gt;
&lt;li&gt;Modern microservices, HTTP/2, and streaming -&amp;gt; gRPC&lt;/li&gt;
&lt;li&gt;gRPC-style APIs needing broad HTTP compatibility (browser and backend) -&amp;gt; Connect&lt;/li&gt;
&lt;li&gt;Existing Thrift ecosystems or cross-language protocol/transport flexibility -&amp;gt; Apache Thrift&lt;/li&gt;
&lt;li&gt;Enterprise and standards-driven integrations -&amp;gt; SOAP&lt;/li&gt;
&lt;li&gt;Lightweight RPC over JSON -&amp;gt; JSON-RPC&lt;/li&gt;
&lt;li&gt;Legacy XML-RPC interoperability -&amp;gt; XML-RPC
&lt;/li&gt;
&lt;/ol&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TD

A[Need an RPC System] --&amp;gt; B{Entire stack uses TypeScript?}

B --&amp;gt;|Yes| C{Need end-to-end&amp;lt;br/&amp;gt;TypeScript inference?}
C --&amp;gt;|Yes| TRPC[tRPC]
C --&amp;gt;|No| D

B --&amp;gt;|No| D{Need broad HTTP compatibility&amp;lt;br/&amp;gt;across browser and backend clients?}

D --&amp;gt;|Yes| CONNECT[Connect]
D --&amp;gt;|No| E

E{Building internal&amp;lt;br/&amp;gt;microservices?}

E --&amp;gt;|Yes| F{Already using Thrift, or need&amp;lt;br/&amp;gt;flexible protocols/transports&amp;lt;br/&amp;gt;across many languages?}

F --&amp;gt;|Yes| THRIFT[Apache Thrift]
F --&amp;gt;|No| GRPC[gRPC]

E --&amp;gt;|No| G

G{Enterprise integration&amp;lt;br/&amp;gt;or WS-* requirements?}

G --&amp;gt;|Yes| SOAP[SOAP]
G --&amp;gt;|No| H

H{Must integrate with&amp;lt;br/&amp;gt;legacy XML-RPC systems?}

H --&amp;gt;|Yes| XMLRPC[XML-RPC]
H --&amp;gt;|No| JSONRPC[JSON-RPC]&lt;/code&gt;&lt;/pre&gt;






&lt;h2&gt;
  
  
  Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;JSON-RPC&lt;/th&gt;
&lt;th&gt;XML-RPC&lt;/th&gt;
&lt;th&gt;SOAP&lt;/th&gt;
&lt;th&gt;Apache Thrift&lt;/th&gt;
&lt;th&gt;gRPC&lt;/th&gt;
&lt;th&gt;Connect&lt;/th&gt;
&lt;th&gt;tRPC&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Mental Model&lt;/td&gt;
&lt;td&gt;Remote method calls&lt;/td&gt;
&lt;td&gt;Remote method calls&lt;/td&gt;
&lt;td&gt;Service operations and contracts&lt;/td&gt;
&lt;td&gt;Shared contracts across languages&lt;/td&gt;
&lt;td&gt;Fast, contract-driven function calls&lt;/td&gt;
&lt;td&gt;Service methods&lt;/td&gt;
&lt;td&gt;Type-safe function calls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transport Protocol&lt;/td&gt;
&lt;td&gt;Usually HTTP, WebSocket, TCP&lt;/td&gt;
&lt;td&gt;Usually HTTP&lt;/td&gt;
&lt;td&gt;Usually HTTP&lt;/td&gt;
&lt;td&gt;Multiple transports&lt;/td&gt;
&lt;td&gt;HTTP/2&lt;/td&gt;
&lt;td&gt;HTTP/1.1 and HTTP/2&lt;/td&gt;
&lt;td&gt;HTTP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Serialization Format&lt;/td&gt;
&lt;td&gt;JSON&lt;/td&gt;
&lt;td&gt;XML&lt;/td&gt;
&lt;td&gt;XML&lt;/td&gt;
&lt;td&gt;Binary protocols&lt;/td&gt;
&lt;td&gt;Protocol Buffers&lt;/td&gt;
&lt;td&gt;Protocol Buffers or JSON&lt;/td&gt;
&lt;td&gt;Native TypeScript types over JSON&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Performance&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Very High&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Type Safety&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Very High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Browser Support&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Limited without proxies&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Language Support&lt;/td&gt;
&lt;td&gt;Broad&lt;/td&gt;
&lt;td&gt;Broad&lt;/td&gt;
&lt;td&gt;Broad&lt;/td&gt;
&lt;td&gt;Broad&lt;/td&gt;
&lt;td&gt;Broad&lt;/td&gt;
&lt;td&gt;Broad&lt;/td&gt;
&lt;td&gt;TypeScript-focused&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complexity&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Typical Use Cases&lt;/td&gt;
&lt;td&gt;Lightweight APIs, protocol integrations&lt;/td&gt;
&lt;td&gt;Legacy systems&lt;/td&gt;
&lt;td&gt;Enterprise integrations&lt;/td&gt;
&lt;td&gt;Polyglot backend systems&lt;/td&gt;
&lt;td&gt;Microservices, platform infrastructure&lt;/td&gt;
&lt;td&gt;Browser-friendly RPC, modern APIs&lt;/td&gt;
&lt;td&gt;Full-stack TypeScript applications&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strengths&lt;/td&gt;
&lt;td&gt;Simplicity, easy tooling, human-readable&lt;/td&gt;
&lt;td&gt;Simplicity and legacy compatibility&lt;/td&gt;
&lt;td&gt;Standardization, enterprise features&lt;/td&gt;
&lt;td&gt;Efficient cross-language communication&lt;/td&gt;
&lt;td&gt;Performance, streaming, ecosystem&lt;/td&gt;
&lt;td&gt;Interoperability and browser support&lt;/td&gt;
&lt;td&gt;Outstanding developer experience&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Weaknesses&lt;/td&gt;
&lt;td&gt;Weak contracts and typing&lt;/td&gt;
&lt;td&gt;Verbose XML and limited capabilities&lt;/td&gt;
&lt;td&gt;Complexity and operational overhead&lt;/td&gt;
&lt;td&gt;Smaller ecosystem than gRPC&lt;/td&gt;
&lt;td&gt;Browser constraints and operational complexity&lt;/td&gt;
&lt;td&gt;Newer ecosystem&lt;/td&gt;
&lt;td&gt;Limited outside TypeScript&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Evolution View
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Era&lt;/th&gt;
&lt;th&gt;Common Technologies&lt;/th&gt;
&lt;th&gt;Primary Goal&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Early Web Services&lt;/td&gt;
&lt;td&gt;XML-RPC, SOAP&lt;/td&gt;
&lt;td&gt;Standardized remote communication over HTTP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Distributed Service Platforms&lt;/td&gt;
&lt;td&gt;Apache Thrift&lt;/td&gt;
&lt;td&gt;Efficient cross-language RPC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloud-Native Systems&lt;/td&gt;
&lt;td&gt;gRPC&lt;/td&gt;
&lt;td&gt;High-performance service communication&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Modern Web-Friendly RPC&lt;/td&gt;
&lt;td&gt;Connect&lt;/td&gt;
&lt;td&gt;Better HTTP and browser interoperability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TypeScript-First Development&lt;/td&gt;
&lt;td&gt;tRPC&lt;/td&gt;
&lt;td&gt;End-to-end type safety and developer productivity&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  XML-RPC
&lt;/h2&gt;

&lt;p&gt;In the late 1990s, distributed systems were difficult to integrate. Common approaches included:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CORBA
DCOM
RMI
Custom TCP Protocols
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These were often:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vendor-specific&lt;/li&gt;
&lt;li&gt;Complex&lt;/li&gt;
&lt;li&gt;Difficult to integrate across platforms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Developers wanted something that worked over HTTP using XML. XML-RPC was created in 1998 and provided a simple way to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Call a function&lt;/li&gt;
&lt;li&gt;Across a network&lt;/li&gt;
&lt;li&gt;Using HTTP&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It was one of the first widely adopted web-service protocols.&lt;/p&gt;

&lt;h3&gt;
  
  
  XML-RPC thinks in remote function calls
&lt;/h3&gt;

&lt;p&gt;XML-RPC assumes: Services expose methods, and clients call those methods remotely. Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /users/123
POST /orders
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;XML-RPC says:&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="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;createOrder&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Core assumption: Network services should look like callable functions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Request&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;methodCall&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;methodName&amp;gt;&lt;/span&gt;getUser&lt;span class="nt"&gt;&amp;lt;/methodName&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;params&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;param&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;int&amp;gt;&lt;/span&gt;123&lt;span class="nt"&gt;&amp;lt;/int&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/params&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/methodCall&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Response&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;methodResponse&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;params&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;param&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;struct&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;member&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;id&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&amp;lt;int&amp;gt;&lt;/span&gt;123&lt;span class="nt"&gt;&amp;lt;/int&amp;gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/member&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;member&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;name&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;Alice&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/member&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/struct&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/params&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/methodResponse&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is effectively &lt;code&gt;getUser(123)&lt;/code&gt; over HTTP.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Simple RPC model&lt;/td&gt;
&lt;td&gt;Very verbose XML payloads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cross-platform interoperability&lt;/td&gt;
&lt;td&gt;Weak typing and contracts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Human-readable messages&lt;/td&gt;
&lt;td&gt;Slow parsing compared to JSON/Protobuf&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uses standard HTTP transport&lt;/td&gt;
&lt;td&gt;Large message sizes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Easy firewall traversal&lt;/td&gt;
&lt;td&gt;Limited modern tooling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Historically important&lt;/td&gt;
&lt;td&gt;Rarely used in new systems&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Influenced later web-service designs&lt;/td&gt;
&lt;td&gt;Mostly replaced by newer technologies&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  SOAP
&lt;/h2&gt;

&lt;p&gt;As businesses started integrating systems across organizations, they needed more than simple remote procedure calls. Companies wanted:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Security&lt;/li&gt;
&lt;li&gt;Reliability&lt;/li&gt;
&lt;li&gt;Transactions&lt;/li&gt;
&lt;li&gt;Formal Contracts&lt;/li&gt;
&lt;li&gt;Interoperability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SOAP (Simple Object Access Protocol) was introduced in 1998 and became a W3C standard in the early 2000s. SOAP attempted to standardize enterprise communication across platforms and vendors.&lt;/p&gt;

&lt;h3&gt;
  
  
  SOAP thinks in contracts and messages
&lt;/h3&gt;

&lt;p&gt;Core assumption: Distributed systems need formal agreements about communication.&lt;/p&gt;

&lt;p&gt;A SOAP service is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Contract (WSDL)
      +
Message Format
      +
Enterprise Standards
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;SOAP Request&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;soap:Envelope&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;soap:Body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;GetUser&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;Id&amp;gt;&lt;/span&gt;123&lt;span class="nt"&gt;&amp;lt;/Id&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/GetUser&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/soap:Body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/soap:Envelope&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SOAP Response&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;soap:Envelope&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;soap:Body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;GetUserResponse&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;User&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Id&amp;gt;&lt;/span&gt;123&lt;span class="nt"&gt;&amp;lt;/Id&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Name&amp;gt;&lt;/span&gt;Alice&lt;span class="nt"&gt;&amp;lt;/Name&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/User&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/GetUserResponse&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/soap:Body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/soap:Envelope&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  WS-* Standards
&lt;/h3&gt;

&lt;p&gt;SOAP is commonly paired with a family of enterprise standards known as &lt;strong&gt;WS-&lt;/strong&gt;* ("WS-star"), including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;WS-Security&lt;/strong&gt; – message-level encryption, signing, and authentication&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WS-ReliableMessaging&lt;/strong&gt; – guaranteed, ordered message delivery even over unreliable networks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WS-AtomicTransaction&lt;/strong&gt; – coordinating distributed transactions across multiple services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These standards are why SOAP remained the go-to choice for banking, insurance, and government systems that needed guarantees plain HTTP alone couldn't provide.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Strong formal contracts (WSDL)&lt;/td&gt;
&lt;td&gt;Extremely verbose XML&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enterprise-grade security&lt;/td&gt;
&lt;td&gt;High complexity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reliable messaging support&lt;/td&gt;
&lt;td&gt;Large payload sizes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Distributed transaction support&lt;/td&gt;
&lt;td&gt;Slower than modern alternatives&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mature enterprise tooling&lt;/td&gt;
&lt;td&gt;Difficult developer experience&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strong interoperability guarantees&lt;/td&gt;
&lt;td&gt;Heavyweight for simple APIs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Common in regulated industries&lt;/td&gt;
&lt;td&gt;Rarely chosen for new projects&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  JSON-RPC
&lt;/h2&gt;

&lt;p&gt;JSON-RPC first appeared around 2005, emerging as a lightweight alternative to XML-RPC and SOAP.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why was it created?
&lt;/h3&gt;

&lt;p&gt;At the time, many RPC systems used XML-RPC and SOAP which were powerful but verbose and cumbersome.&lt;/p&gt;

&lt;p&gt;Developers wanted:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simpler payloads&lt;/li&gt;
&lt;li&gt;Easier parsing&lt;/li&gt;
&lt;li&gt;Better JavaScript compatibility&lt;/li&gt;
&lt;li&gt;Less bandwidth usage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;JSON-RPC replaced XML with JSON while keeping the RPC model. JSON-RPC provided a standard way to represent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Method Name
Parameters
Result
Error
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;using JSON.&lt;/p&gt;

&lt;h3&gt;
  
  
  JSON-RPC thinks in remote function calls
&lt;/h3&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /users
GET /users/123
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JSON-RPC says:&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="nf"&gt;createUser&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server exposes a set of methods. The client invokes them. Core assumption: APIs are collections of operations, not collections of resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Request:&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;"jsonrpc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"getUser"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"params"&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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;123&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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&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;Response:&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;"jsonrpc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"result"&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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;123&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;"Alice"&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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&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;The API feels like &lt;code&gt;getUser(123)&lt;/code&gt; even though it is happening across the network.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where JSON-RPC shows up today
&lt;/h3&gt;

&lt;p&gt;JSON-RPC quietly powers several widely-used systems, including Ethereum and other blockchain node APIs, Bitcoin Core's RPC interface, and the Language Server Protocol (LSP) used by code editors like VS Code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Very simple protocol&lt;/td&gt;
&lt;td&gt;Not resource-oriented&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lightweight JSON payloads&lt;/td&gt;
&lt;td&gt;Limited ecosystem&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transport agnostic&lt;/td&gt;
&lt;td&gt;Weak standardization outside core spec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Natural fit for command-style APIs&lt;/td&gt;
&lt;td&gt;Loses many HTTP benefits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supports batch requests&lt;/td&gt;
&lt;td&gt;Can become method-heavy over time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Easy to implement&lt;/td&gt;
&lt;td&gt;Less tooling than gRPC or GraphQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Works well over WebSockets&lt;/td&gt;
&lt;td&gt;No built-in typing or schema system&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  gRPC
&lt;/h2&gt;

&lt;p&gt;gRPC, open-sourced by Google in 2015, evolved from Stubby, Google's internal RPC framework. Google operated thousands of services communicating with each other across data centers. gRPC was designed to make service-to-service communication:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster&lt;/li&gt;
&lt;li&gt;Strongly typed&lt;/li&gt;
&lt;li&gt;Easier to maintain&lt;/li&gt;
&lt;li&gt;Easier to generate clients for&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  gRPC thinks in fast, contract-driven function calls over HTTP/2
&lt;/h3&gt;

&lt;p&gt;Local function:&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="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;gRPC function:&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;userService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;GetUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The client behaves as if it's calling a local function, but the execution happens on another machine.&lt;/p&gt;

&lt;p&gt;Core assumption: "Modern service-to-service communication should feel like calling a local function, while running on HTTP/2 with strong typing, low latency, and native streaming." This is what separates gRPC from earlier RPC systems. It isn't just "remote functions," it's remote functions built for high-performance, cloud-native microservices.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Service Definition&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;&lt;span class="na"&gt;syntax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"proto3"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;service&lt;/span&gt; &lt;span class="n"&gt;UserService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;rpc&lt;/span&gt; &lt;span class="n"&gt;GetUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GetUserRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;GetUserRequest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int32&lt;/span&gt; &lt;span class="na"&gt;id&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="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int32&lt;/span&gt; &lt;span class="na"&gt;id&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="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;name&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Client call:&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;const&lt;/span&gt; &lt;span class="nx"&gt;user&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;123&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;"Alice"&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;Because gRPC uses Protocol Buffers with numbered fields, services can add new fields over time without breaking existing clients which is a key reason contract-first systems like gRPC and Thrift age well in large codebases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Streaming in gRPC
&lt;/h3&gt;

&lt;p&gt;Unlike JSON-RPC, XML-RPC, or SOAP, gRPC supports more than simple request/response calls. It defines four call patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unary RPC&lt;/strong&gt; – one request, one response (a normal function call).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server Streaming&lt;/strong&gt; – one request, a stream of responses (e.g., live price updates).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Client Streaming&lt;/strong&gt; – a stream of requests, one final response (e.g., uploading data in chunks).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bidirectional Streaming&lt;/strong&gt; – both sides stream independently at the same time (e.g., chat, live collaboration).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example of a server-streaming method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;&lt;span class="kd"&gt;service&lt;/span&gt; &lt;span class="n"&gt;UserService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;rpc&lt;/span&gt; &lt;span class="n"&gt;WatchUserUpdates&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GetUserRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="n"&gt;User&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 built-in streaming is one of the main reasons teams pick gRPC over JSON-RPC or REST when they need continuous or real-time data flow, not just one-off calls.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Extremely fast and efficient&lt;/td&gt;
&lt;td&gt;Poor native browser support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strongly typed contracts&lt;/td&gt;
&lt;td&gt;Binary protocol is harder to inspect&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Automatic client/server code generation&lt;/td&gt;
&lt;td&gt;Requires Protobuf tooling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Built-in streaming support&lt;/td&gt;
&lt;td&gt;Higher learning curve&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Excellent for microservices&lt;/td&gt;
&lt;td&gt;More tightly coupled contracts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-language support&lt;/td&gt;
&lt;td&gt;Often unnecessary for simple CRUD APIs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP/2 performance benefits&lt;/td&gt;
&lt;td&gt;Public APIs usually favor REST&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Apache Thrift
&lt;/h2&gt;

&lt;p&gt;Apache Thrift was created at Facebook in 2007 and later donated to the Apache Software Foundation in 2008.&lt;/p&gt;

&lt;p&gt;Facebook's infrastructure was growing rapidly and services were being written in different languages (PHP, Java, C++, Python). Each service needed to communicate with others. Without a common framework, teams had to manually create:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Serialization formats&lt;/li&gt;
&lt;li&gt;Network protocols&lt;/li&gt;
&lt;li&gt;Client SDKs&lt;/li&gt;
&lt;li&gt;Server SDKs for every language combination.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Facebook wanted: "Define a service once, generate clients and servers everywhere." Thrift unified data serialization, RPC framework, and code generation into a single system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Thrift thinks in shared contracts across languages
&lt;/h3&gt;

&lt;p&gt;Core assumption: "A single Interface Definition Language (IDL) contract should let completely different languages, protocols, and transports interoperate without hand-written glue code for every combination."&lt;/p&gt;

&lt;p&gt;Where Thrift distinguishes itself is flexibility: it doesn't lock a system into one protocol or one transport the way many RPC systems do.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Contract
   ↓
Generated Code (any language)
   ↓
Network Communication (any supported protocol/transport)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /users/123
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thrift says:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;service UserService {
  User getUser(1:id)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Core assumption: "Cross-language communication in large, heterogeneous systems should be generated from a shared contract, with the freedom to choose the protocol and transport that fits each situation."&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Thrift IDL&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct User {
  1: i32 id
  2: string name
}

service UserService {
  User getUser(1:i32 id)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Generate code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;thrift &lt;span class="nt"&gt;--gen&lt;/span&gt; java user.thrift
thrift &lt;span class="nt"&gt;--gen&lt;/span&gt; go user.thrift
thrift &lt;span class="nt"&gt;--gen&lt;/span&gt; py user.thrift
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Client:&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="n"&gt;user&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="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&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="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Strong contract-first design&lt;/td&gt;
&lt;td&gt;More complex than REST&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Excellent multi-language support&lt;/td&gt;
&lt;td&gt;Weak browser support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High-performance binary serialization&lt;/td&gt;
&lt;td&gt;Smaller ecosystem than gRPC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Automatic code generation&lt;/td&gt;
&lt;td&gt;Additional operational complexity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flexible protocols and transports&lt;/td&gt;
&lt;td&gt;Steeper learning curve&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mature RPC framework&lt;/td&gt;
&lt;td&gt;Overkill for simple applications&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Good fit for polyglot systems&lt;/td&gt;
&lt;td&gt;More moving parts than REST&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Connect
&lt;/h2&gt;

&lt;p&gt;Connect was created by Buf Technologies and publicly introduced around 2021–2022.&lt;/p&gt;

&lt;p&gt;Native gRPC works well between servers but struggles in browsers because browsers do not expose the full HTTP/2 capabilities that gRPC relies on. Developers had to build extra components for browser support.&lt;/p&gt;

&lt;p&gt;Connect keeps the good parts of gRPC while making APIs work across browsers, mobile apps, backend services, and CLI tools, without requiring specialized infrastructure. Importantly, Connect isn't just "gRPC for browsers". Many teams adopt it purely for backend-to-backend communication, because it works over standard HTTP/1.1 and HTTP/2 without the operational overhead (proxies, specialized load balancers) that plain gRPC often requires.&lt;/p&gt;

&lt;h3&gt;
  
  
  Connect thinks in RPCs over standard HTTP
&lt;/h3&gt;

&lt;p&gt;Core assumption: RPC contracts should work everywhere HTTP works, for browser and backend clients alike. Instead of choosing between:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;REST for browsers
gRPC for services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Connect tries to provide:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;One Contract
One API
Every Client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Service Definition&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Same &lt;code&gt;.proto&lt;/code&gt; file as gRPC:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;&lt;span class="na"&gt;syntax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"proto3"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;service&lt;/span&gt; &lt;span class="n"&gt;UserService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;rpc&lt;/span&gt; &lt;span class="n"&gt;GetUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GetUserRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&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;Generate client/server code.&lt;/p&gt;

&lt;p&gt;Client:&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;const&lt;/span&gt; &lt;span class="nx"&gt;response&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;123&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difference is largely in transport and compatibility. Connect defines a protocol that works over ordinary HTTP. Unlike gRPC, it does not require specialized HTTP/2 behavior for basic usage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Browser-friendly RPC&lt;/td&gt;
&lt;td&gt;Smaller ecosystem&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reuses existing Protobuf contracts&lt;/td&gt;
&lt;td&gt;Less industry adoption&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strong typing and code generation&lt;/td&gt;
&lt;td&gt;Primarily useful for gRPC-style architectures&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Works with standard HTTP infrastructure&lt;/td&gt;
&lt;td&gt;Fewer learning resources&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supports Connect, gRPC, and gRPC-Web&lt;/td&gt;
&lt;td&gt;Additional technology choice&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Easier deployment than gRPC-Web stacks&lt;/td&gt;
&lt;td&gt;Not as universally recognized as REST&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Good full-stack developer experience&lt;/td&gt;
&lt;td&gt;Can be overkill for simple APIs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  tRPC
&lt;/h2&gt;

&lt;p&gt;Modern TypeScript applications often looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Frontend
    |
 REST/GraphQL
    |
Backend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even though both sides were written in TypeScript, developers still had to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define API routes&lt;/li&gt;
&lt;li&gt;Create schemas&lt;/li&gt;
&lt;li&gt;Generate types&lt;/li&gt;
&lt;li&gt;Synchronize contracts This often felt redundant. Example:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;might need to be defined multiple times across frontend and backend. tRPC was created by Alex Johansson around 2021. It uses TypeScript itself as the contract.&lt;/p&gt;

&lt;h3&gt;
  
  
  tRPC thinks in TypeScript functions
&lt;/h3&gt;

&lt;p&gt;Core assumption: The frontend and backend belong to the same codebase and can share types directly. tRPC uses TypeScript types as the source of truth.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Server&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;appRouter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;router&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;publicProcedure&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;number&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;input&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;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alice&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="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Client&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&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;trpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;123&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="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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;TypeScript automatically knows &lt;code&gt;user.id&lt;/code&gt; and &lt;code&gt;user.name&lt;/code&gt; without code generation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;End-to-end type safety&lt;/td&gt;
&lt;td&gt;TypeScript-only ecosystem&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No code generation required&lt;/td&gt;
&lt;td&gt;Weak cross-language support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Excellent developer experience&lt;/td&gt;
&lt;td&gt;Tight frontend/backend coupling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fast development speed&lt;/td&gt;
&lt;td&gt;Not ideal for public APIs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Great autocomplete and inference&lt;/td&gt;
&lt;td&gt;Smaller ecosystem&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Perfect for monorepos&lt;/td&gt;
&lt;td&gt;Less suitable for large microservice environments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Minimal boilerplate&lt;/td&gt;
&lt;td&gt;Harder to integrate with non-TypeScript systems&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JSON-RPC&lt;/strong&gt; – Choose it for lightweight, transport-agnostic method calls, especially when you already have a JSON-friendly client and don't need strong typing or contracts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;XML-RPC&lt;/strong&gt; – Only relevant when integrating with legacy systems that already speak it. Avoid for new projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SOAP&lt;/strong&gt; – Choose it when you need formal contracts (WSDL) and enterprise-grade guarantees like security, reliable messaging, or distributed transactions (WS-*) like banking, insurance, and government systems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apache Thrift&lt;/strong&gt; – Choose it for large, polyglot backend systems, especially if you need protocol/transport flexibility or already have Thrift infrastructure in place.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;gRPC&lt;/strong&gt; – Choose it for modern, performance-sensitive microservices that benefit from HTTP/2, strong typing, and native streaming. Avoid for public browser-facing APIs without a proxy layer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connect&lt;/strong&gt; – Choose it when you want gRPC-style contracts with simpler HTTP compatibility across browsers, backends, and mobile clients, without the operational overhead of plain gRPC.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;tRPC&lt;/strong&gt; – Choose it for full-stack TypeScript applications, especially monorepos, where end-to-end type safety and developer speed matter more than cross-language support.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>api</category>
      <category>tutorial</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>Request/Response APIs: REST vs GraphQL vs OData vs Falcor</title>
      <dc:creator>Shiv Rai (S_RAI)</dc:creator>
      <pubDate>Mon, 14 Sep 2026 14:08:50 +0000</pubDate>
      <link>https://dev.to/rai_shiv/requestresponse-apis-rest-vs-graphql-vs-odata-vs-falcor-b52</link>
      <guid>https://dev.to/rai_shiv/requestresponse-apis-rest-vs-graphql-vs-odata-vs-falcor-b52</guid>
      <description>&lt;h2&gt;
  
  
  What are Request/Response APIs?
&lt;/h2&gt;

&lt;p&gt;Request/Response APIs are the most common way for applications to communicate across process, network, or service boundaries. A client sends a request for information or an action, and a server returns a response containing the result.&lt;/p&gt;

&lt;p&gt;This model is simple, predictable, and well-suited to workloads where a consumer knows when it needs data and expects an immediate answer. Web applications, mobile apps, dashboards, internal tools, and third-party integrations all commonly rely on request/response communication.&lt;/p&gt;

&lt;p&gt;Common use cases include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CRUD applications&lt;/li&gt;
&lt;li&gt;Web and mobile backends&lt;/li&gt;
&lt;li&gt;Public developer platforms&lt;/li&gt;
&lt;li&gt;Internal business systems&lt;/li&gt;
&lt;li&gt;Reporting and analytics APIs&lt;/li&gt;
&lt;li&gt;Data access layers for enterprise applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article includes: REST, GraphQL, Falcor, OData.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to choose?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Simplicity, interoperability, and widespread ecosystem support -&amp;gt; REST&lt;/li&gt;
&lt;li&gt;Clients need flexible access to complex data -&amp;gt; GraphQL&lt;/li&gt;
&lt;li&gt;Efficient access to large, connected data graphs -&amp;gt; Falcor&lt;/li&gt;
&lt;li&gt;Standardization, querying capabilities, and enterprise integration are primary concerns -&amp;gt; OData
&lt;/li&gt;
&lt;/ol&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TD

A[Need a Request/Response API] --&amp;gt; B{Need a standardized query language&amp;lt;br/&amp;gt;for business data and integrations?}

B --&amp;gt;|Yes| O[OData]
B --&amp;gt;|No| C{Do clients need precise control&amp;lt;br/&amp;gt;over returned fields and shapes?}

C --&amp;gt;|No| R[REST]
C --&amp;gt;|Yes| D{Are you building around a&amp;lt;br/&amp;gt;single logical data graph with&amp;lt;br/&amp;gt;heavy client-side navigation?}

D --&amp;gt;|Yes| F[Falcor]
D --&amp;gt;|No| G[GraphQL]&lt;/code&gt;&lt;/pre&gt;






&lt;h2&gt;
  
  
  Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;REST&lt;/th&gt;
&lt;th&gt;GraphQL&lt;/th&gt;
&lt;th&gt;Falcor&lt;/th&gt;
&lt;th&gt;OData&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Mental Model&lt;/td&gt;
&lt;td&gt;Resources exposed through endpoints&lt;/td&gt;
&lt;td&gt;Query a graph of data&lt;/td&gt;
&lt;td&gt;Navigate a virtual JSON graph&lt;/td&gt;
&lt;td&gt;Resources enhanced by a standardized query language&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data Fetching Flexibility&lt;/td&gt;
&lt;td&gt;Low to Medium&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Medium to High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Client Control&lt;/td&gt;
&lt;td&gt;Limited by endpoints&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complexity&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Medium to High&lt;/td&gt;
&lt;td&gt;Medium to High&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Caching&lt;/td&gt;
&lt;td&gt;Excellent and well understood&lt;/td&gt;
&lt;td&gt;More challenging&lt;/td&gt;
&lt;td&gt;Good with graph-aware tooling&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tooling&lt;/td&gt;
&lt;td&gt;Extremely mature&lt;/td&gt;
&lt;td&gt;Mature and growing&lt;/td&gt;
&lt;td&gt;Smaller ecosystem&lt;/td&gt;
&lt;td&gt;Strong enterprise ecosystem&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Learning Curve&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Medium to High&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Typical Use Cases&lt;/td&gt;
&lt;td&gt;Public APIs, web services, CRUD systems&lt;/td&gt;
&lt;td&gt;Frontend-heavy applications, aggregating multiple data sources&lt;/td&gt;
&lt;td&gt;Rich data-driven applications with complex relationships&lt;/td&gt;
&lt;td&gt;Enterprise systems, analytics, business applications&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strengths&lt;/td&gt;
&lt;td&gt;Simplicity, scalability, broad adoption&lt;/td&gt;
&lt;td&gt;Flexible queries, reduced over/under-fetching&lt;/td&gt;
&lt;td&gt;Efficient graph traversal and data reuse&lt;/td&gt;
&lt;td&gt;Standardized querying and interoperability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Weaknesses&lt;/td&gt;
&lt;td&gt;Multiple requests for related data, endpoint proliferation&lt;/td&gt;
&lt;td&gt;Increased operational and schema complexity&lt;/td&gt;
&lt;td&gt;Smaller adoption and ecosystem&lt;/td&gt;
&lt;td&gt;Can feel verbose and enterprise-oriented&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  REST
&lt;/h2&gt;

&lt;p&gt;REST stands for REpresentational State Transfer. It was introduced by Roy Fielding, one of the creators of HTTP. He published his PhD dissertation in 2000 explaining why the World Wide Web scaled so well. According to him, the web succeeded because it followed certain architectural constraints. This architectural style became known as REST.&lt;/p&gt;

&lt;p&gt;REST offered a simpler model than the RPC-style communication common between systems at the time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Everything important is a resource&lt;/li&gt;
&lt;li&gt;Resources have URLs&lt;/li&gt;
&lt;li&gt;Standard HTTP methods operate on those resources&lt;/li&gt;
&lt;li&gt;Clients and servers remain loosely coupled&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;REST isn't a protocol. It's an architectural style.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Strict REST, as originally defined, includes additional constraints such as HATEOAS (Hypermedia as the Engine of Application State). In practice, many APIs commonly referred to as "REST APIs" do not fully implement every constraint from the original definition — what most teams build and call "REST" is closer to resource-oriented HTTP APIs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  REST thinks in resources
&lt;/h3&gt;

&lt;p&gt;A resource is simply a thing your system exposes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Users&lt;/li&gt;
&lt;li&gt;Books&lt;/li&gt;
&lt;li&gt;Orders&lt;/li&gt;
&lt;li&gt;Authors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of:&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="nf"&gt;createUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;deleteUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;REST is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST   /users
GET    /users/123
DELETE /users/123
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Examples
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Create a user:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Request&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /users

Content-Type: application/json

{
  "name": "Alice"
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Response&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;201 Created

{
  "id": 123,
  "name": "Alice"
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fetch a user:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Request&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /users/123
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Response&lt;/strong&gt;&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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;123&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;"Alice"&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;A representation of a resource is transferred during calls, not the resource itself.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Simple and easy to understand using standard HTTP methods (GET, POST, PUT, DELETE).&lt;/td&gt;
&lt;td&gt;Can lead to overfetching (receiving more data than needed).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Universally supported across browsers, servers, mobile apps, proxies, and CDNs.&lt;/td&gt;
&lt;td&gt;Can lead to underfetching (multiple requests needed to gather related data).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Leverages existing HTTP infrastructure and tooling.&lt;/td&gt;
&lt;td&gt;No built-in strong typing or schema enforcement.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cache-friendly through HTTP caching headers and CDN support.&lt;/td&gt;
&lt;td&gt;API contracts are often documented separately and validated at runtime.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resource-oriented design maps naturally to CRUD operations.&lt;/td&gt;
&lt;td&gt;Modeling complex business actions can become awkward.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stateless architecture improves scalability and reliability.&lt;/td&gt;
&lt;td&gt;Real-time communication is not natively supported.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Human-readable requests and responses simplify debugging.&lt;/td&gt;
&lt;td&gt;Versioning strategies can become complicated over time.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Loose coupling between clients and servers allows independent evolution.&lt;/td&gt;
&lt;td&gt;Deeply nested or relational data often requires multiple round trips.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Easy to test using browsers, curl, Postman, or similar tools.&lt;/td&gt;
&lt;td&gt;Performance may suffer in chatty client-server interactions.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Large ecosystem, mature best practices, and widespread adoption.&lt;/td&gt;
&lt;td&gt;Different teams often interpret REST principles differently, leading to inconsistent APIs.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  GraphQL
&lt;/h2&gt;

&lt;p&gt;Facebook developed GraphQL internally in 2012 to tackle the difficulty of working with REST APIs as their mobile apps grew. Facebook open-sourced GraphQL in 2015.&lt;/p&gt;

&lt;p&gt;Mobile clients often faced problems such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Slow networks&lt;/li&gt;
&lt;li&gt;Limited bandwidth&lt;/li&gt;
&lt;li&gt;Multiple API requests for a single screen&lt;/li&gt;
&lt;li&gt;Different data requirements across platforms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;REST forces the server to decide what data is returned. GraphQL lets the client decide. Instead of many endpoints, GraphQL provides a single endpoint, &lt;code&gt;/graphql&lt;/code&gt;, through which all actions take place.&lt;/p&gt;

&lt;h3&gt;
  
  
  GraphQL thinks in queries
&lt;/h3&gt;

&lt;p&gt;The client describes the exact structure of the response. The client requests fields, and the server assembles the response.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;A user has:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;id
name
email
avatar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Client only needs name.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Query&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&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="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;123&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="n"&gt;name&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;p&gt;&lt;strong&gt;Response&lt;/strong&gt;&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;"data"&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;"user"&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;"Alice"&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;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;Client needs name + email:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Query&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&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="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;123&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="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;email&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;p&gt;&lt;strong&gt;Response&lt;/strong&gt;&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;"data"&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;"user"&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;"Alice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alice@example.com"&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;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;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Eliminates overfetching&lt;/td&gt;
&lt;td&gt;More complex backend architecture&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reduces underfetching and multiple requests&lt;/td&gt;
&lt;td&gt;Caching is harder than REST&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strong schema and typing&lt;/td&gt;
&lt;td&gt;Can suffer from N+1 query issues&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Excellent tooling and developer experience&lt;/td&gt;
&lt;td&gt;Query complexity must be controlled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flexible for multiple client types&lt;/td&gt;
&lt;td&gt;Overkill for simple CRUD systems&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-documenting schema&lt;/td&gt;
&lt;td&gt;Additional learning curve&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Easier API evolution&lt;/td&gt;
&lt;td&gt;Monitoring and performance tuning are harder&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Falcor
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A note on relevance:&lt;/strong&gt; Falcor is included here primarily for historical and conceptual understanding — it introduced ideas (like a unified virtual data graph) that are useful for building intuition. In practice, GraphQL became the dominant solution for flexible, client-driven data fetching.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Falcor was created by Netflix and open-sourced in 2015. Netflix applications needed data from many backend services:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Recommendations
User Profiles
Ratings
Viewing History
Search
Metadata
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Building a screen often required multiple API calls. This created:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Overfetching&lt;/li&gt;
&lt;li&gt;Underfetching&lt;/li&gt;
&lt;li&gt;High latency&lt;/li&gt;
&lt;li&gt;Complex frontend code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Falcor introduced a concept called the JSON Graph. Instead of exposing APIs as resources or functions, the server exposes a graph of interconnected data. The client requests paths through that graph.&lt;/p&gt;

&lt;h3&gt;
  
  
  Falcor thinks in graphs
&lt;/h3&gt;

&lt;p&gt;Imagine application data as one giant object:&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="nl"&gt;users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="nx"&gt;movies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="nx"&gt;ratings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="nx"&gt;recommendations&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;Clients don't call endpoints. They ask for paths inside the graph.&lt;/p&gt;

&lt;p&gt;Example:&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;users&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
&lt;span class="nx"&gt;movies&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;rating&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Core assumption: Application data is a graph, and clients should navigate that graph directly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Suppose the graph contains:&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="nl"&gt;users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alice&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Client requests:&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;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&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&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&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;Response:&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;"jsonGraph"&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;"users"&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;"123"&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;"Alice"&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;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;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Flexible graph-based data access&lt;/td&gt;
&lt;td&gt;Steeper learning curve&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Built-in client caching&lt;/td&gt;
&lt;td&gt;Small ecosystem&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reduces API round trips&lt;/td&gt;
&lt;td&gt;Limited adoption&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Handles relationships naturally&lt;/td&gt;
&lt;td&gt;GraphQL largely replaced it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Efficient for connected data&lt;/td&gt;
&lt;td&gt;Fewer tools and community resources&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Client-driven fetching&lt;/td&gt;
&lt;td&gt;Complex mental model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Good Netflix-scale use cases&lt;/td&gt;
&lt;td&gt;Rarely chosen for new projects&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  OData
&lt;/h2&gt;

&lt;p&gt;As organizations exposed more data over HTTP, developers repeatedly faced the same problems:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /users
GET /products
GET /orders
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every API invented its own way to support:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Filtering&lt;/li&gt;
&lt;li&gt;Sorting&lt;/li&gt;
&lt;li&gt;Pagination&lt;/li&gt;
&lt;li&gt;Searching&lt;/li&gt;
&lt;li&gt;Expanding related data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /users?status=active
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;might work in one API, while another used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /users?filter=status:active
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There was no standard way to query data over HTTP. OData (Open Data Protocol) was introduced by Microsoft in 2007 and later standardized through OASIS. OData attempted to create SQL-like querying for HTTP APIs. Instead of every API inventing its own query language, clients could use a standard set of query operations.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Clarification — REST vs. OData:&lt;/strong&gt; Traditional REST APIs usually expose fixed resource representations, meaning the server largely decides what shape a response takes. OData extends REST-style APIs with a standardized querying layer on top, giving clients more control over returned data (filtering, selecting fields, expanding relations) without changing the underlying request/response model.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  OData thinks in queryable resources
&lt;/h3&gt;

&lt;p&gt;Core assumption: APIs expose resources the same way REST does, but those resources are enhanced with a standardized query language — so clients can filter, sort, select fields, and expand relations without the server needing to build a custom endpoint for every variation.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /active-users
GET /users-by-country
GET /top-customers
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you expose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /users
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and allow the client to specify the query. The server provides the data. The client decides how to filter it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Let's say:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /users
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;returns:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&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;"Alice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"country"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"US"&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;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&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;"Bob"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"country"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"IN"&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;p&gt;Client requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /users?$filter=country eq 'US'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&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;"Alice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"country"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"US"&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;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Powerful built-in querying&lt;/td&gt;
&lt;td&gt;Query language complexity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Standardized filtering and sorting&lt;/td&gt;
&lt;td&gt;Can expose expensive operations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reduces endpoint proliferation&lt;/td&gt;
&lt;td&gt;Tight coupling to data models&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Metadata discovery support&lt;/td&gt;
&lt;td&gt;Less flexible than GraphQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Great for business datasets&lt;/td&gt;
&lt;td&gt;Smaller ecosystem&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strong enterprise tooling&lt;/td&gt;
&lt;td&gt;Rarely used for public APIs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP and REST friendly&lt;/td&gt;
&lt;td&gt;Requires careful security controls&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Choose REST&lt;/strong&gt; when you want simplicity, broad tooling support, strong HTTP caching, and your data access patterns are mostly straightforward CRUD.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Choose GraphQL&lt;/strong&gt; when clients have varied or evolving data needs, over/underfetching is a real problem, and you can support the added backend complexity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Choose OData&lt;/strong&gt; when you need standardized, SQL-like querying (filtering, sorting, expanding relations) over business data, especially in enterprise or Microsoft-adjacent ecosystems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Choose Falcor&lt;/strong&gt; rarely, if ever, for new projects — it's mainly useful for understanding the "unified data graph" mental model.&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>webdev</category>
      <category>api</category>
      <category>systemdesign</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Stellar programs for Developers</title>
      <dc:creator>Shiv Rai (S_RAI)</dc:creator>
      <pubDate>Mon, 25 May 2026 09:48:52 +0000</pubDate>
      <link>https://dev.to/rai_shiv/stellar-programs-for-developers-5e00</link>
      <guid>https://dev.to/rai_shiv/stellar-programs-for-developers-5e00</guid>
      <description>&lt;p&gt;If you have been looking for support to build the next big thing on Stellar, this is the article you must read!&lt;/p&gt;

&lt;p&gt;Stellar is a decentralized, public blockchain that is not only faster and cheaper but also more energy-efficient than most public blockchains, with an average cost of $0.0006667 per transaction, a global reach of 180+ countries, $167M TVL, and 5.3s settlement time.&lt;/p&gt;

&lt;p&gt;To help builders and developers, Stellar Development Foundation (SDF) has introduced various programs that you can apply to:&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Instawards&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Offered through local Stellar Ambassador Chapters, Instawards is a small funding opportunity for early-stage builders. It prioritizes builders with strong collaboration, commitment, and execution readiness.&lt;br&gt;
Instawards are the first step toward bigger opportunities in the stellar ecosystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Build Award&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Consisting of 3 tracks - Open, Integration, and RFP - the Build Award provides up to $150k in XLM for teams building on Stellar. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Track:
Teams with a plan to build something new on Stellar.&lt;/li&gt;
&lt;li&gt;Integration Track:
Teams that are either incorporating an existing Stellar tool or dApp into their project OR already have existing significant traction on any chain or off-chain&lt;/li&gt;
&lt;li&gt;RFP Track:
Developers and teams building tools or services, who are prepared to build and ship.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Review Process:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Prescreen: Complete application and eligibility criteria are met&lt;/li&gt;
&lt;li&gt;Panel Review: Projects are evaluated based on ecosystem value, technical feasibility, roadmap clarity, and team capability.&lt;/li&gt;
&lt;li&gt;Revision Window: Teams are given time to make minor revisions to their submission. This happens before the community vote for Open Track; For the RFP and Integration Tracks, reviewers may request changes.&lt;/li&gt;
&lt;li&gt;Community Vote (For Open Track): SCF community members vote on projects. This drives the final decision.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Audit Bank&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;SDF covers audits for SCF-awarded projects&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Public Goods Award&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Public Goods Award supports public goods maintained by the community -  key infrastructure, tools for the ecosystem, data, governance, and more of the Stellar ecosystem.&lt;br&gt;
It is managed through Soroban Governor.&lt;br&gt;
Applications for the Public Goods Award are invitation-only. If you meet the eligibility requirements, make sure to check the #scf-governance discord channel for next review period.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Liquidity Award&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The Liquidity Award provides funding for the initial liquidity needs of financial protocols that have completed security audits and are live on Stellar mainnet. Liquidity Award can provide a Base Liquidity Award of $50K with a Supplemental Liquidity Award of an additional $50k.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Growth Hack&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;It is an 8-week, competition-style GTM/PMF program where 10-15 teams compete with $20k in initial funding to run a 4-week acquisition + 4-week retention campaign. Top performers receive a share of $200k. The program helps teams find PMF and serves as a bridge between development funding and further growth.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fpkszjar8pbj6pvl4cwkc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fpkszjar8pbj6pvl4cwkc.png" alt=" " width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each program has its own requirements and rules. The funds are provided in XLM, which is the native currency of Stellar.&lt;/p&gt;

&lt;p&gt;You can choose which program to apply for based on your stage. If you are just starting out, apply for Instawards. Later, you can apply for SCF.&lt;/p&gt;

&lt;p&gt;Stellar focuses heavily on DeFi products like remittances, asset tokenization, wallets, and payments. So, if you are building something related, you should definitely apply to these programs.&lt;/p&gt;

&lt;p&gt;For more information, read the SCF handbook here: &lt;a href="https://stellar.gitbook.io/scf-handbook" rel="noopener noreferrer"&gt;https://stellar.gitbook.io/scf-handbook&lt;/a&gt;&lt;br&gt;
For information on SCF projects, upcoming rounds, and submission forms for eligible projects: &lt;a href="https://communityfund.stellar.org/" rel="noopener noreferrer"&gt;communityfund.stellar.org&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy developing!&lt;/p&gt;

</description>
      <category>web3</category>
      <category>development</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Pegasus: Your Document's Language Passport, Powered by Lingo.Dev</title>
      <dc:creator>Shiv Rai (S_RAI)</dc:creator>
      <pubDate>Mon, 16 Mar 2026 12:56:40 +0000</pubDate>
      <link>https://dev.to/rai_shiv/pegasus-your-documents-language-passport-powered-by-lingodev-19h1</link>
      <guid>https://dev.to/rai_shiv/pegasus-your-documents-language-passport-powered-by-lingodev-19h1</guid>
      <description>&lt;p&gt;If I asked you "How many languages are there in the world?", what will you say? "500"? "1000"? "5000"? Still not there yet. There are 7000+ languages in the world. Yet, most of us can name around 10-20. English, being the most common, since it is used globally. However, there are people who do not speak English and there are places, where English is not the preferred language for documents. And that is totally fine. Its a wide world. People are free to speak the language they choose. &lt;/p&gt;

&lt;p&gt;However, this creates a gap in communication. One or sometimes more than one party, has to use a translator in order to communicate. People often use tools like Google Translate in such situations. But, what about documents?&lt;br&gt;
Imagine you sent a pdf or docx to someone in English. That person requested a French version. What will you do ? you copy paste your content into a translator, copy paste the response back into your docx, save it, and share it back to the person. This was a single request. For 1 language. There are more than 20 languages spoken by more than half of the world’s population. Let's assume that just half of them requested a version in their language, which means 10. Are you going to repeat the process 10 times ? That's not sensible, right ? Let's assume you are a hard-worker and did it 10 times. Hurray! But wait... you just noticed there is a small change that needs to be done. You made the change in the original document. And then you realize, you have to do the translations again for the 10 requests. &lt;/p&gt;

&lt;p&gt;At this point you are putting in more effort for preparing document for sharing than doing something productive. But what's the solution to this problem? What if you could just make a single file, with all the translations, rendered according to user's preference? Imagine how easy it would be. Create your file, add translations, share a single file, and you are done. Sounds simple, right? Worry not, it is simple with Pegasus.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F428g6k741adjbs88gpdy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F428g6k741adjbs88gpdy.png" alt="Pegasus" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What is Pegasus?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Imagine an app through which you can create a single file with all the required language translations you want, share it with your team, and they can view it in their preferred language, without even needing internet. How amazing would that be? Pegasus is that app!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fz2hpdqhb8uiio6aqc46b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fz2hpdqhb8uiio6aqc46b.png" alt="Doc View" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How Pegasus works?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;You choose your document (txt, docx, pdf), select the languages you want the translations of, add lingo dev API key, choose the output folder. And that's it. You get a .pgs file which you can share with whoever you want and they can open Pegasus, open this .pgs file, and view it in their language (without API key).&lt;/p&gt;

&lt;p&gt;What if someone got the file but their language translation wasn't available? They can add the translations of their language within the .pgs file following the same steps to create the file. The best part, the current translations available aren't removed. New translations are added along with existing translations. &lt;/p&gt;

&lt;p&gt;The app only requires internet connection when you need translations. Otherwise, it can be used to view files and their translations without the need of internet. Reason, the single file contains all the data required. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fw9yd7fiebey2kmyqqhzc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fw9yd7fiebey2kmyqqhzc.png" alt="Language Selection" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How it's made?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;It's made using Electron.js + Vite + react in typescript, along with tailwindCSS and powered by Lingo.Dev&lt;br&gt;
Lingo Dev's API is used for document content translation while Lingo Dev's Compiler is used to translate the UI content of Pegasus app.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;GitHub Repo&lt;/u&gt;: &lt;a href="https://github.com/ShivRaiGithub/pegasus" rel="noopener noreferrer"&gt;https://github.com/ShivRaiGithub/pegasus&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fdxbfm3xq2mn8ac9uvwe5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fdxbfm3xq2mn8ac9uvwe5.png" alt="Conversion page 2" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Problem Pegasus solves&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;BILLIONS of digital documents require translations EVERYDAY. Business contracts, government papers, product manuals, etc are examples of some documents whose digital versions need various translations for multiple languages. Large companies usually maintain more than 5 language versions of same document. This piles up in costs, leading to thousands of dollars just to maintain few documents. These costs can be reduced multi-fold. What do you think is the market size of multilingual document translation ? More than $60B. But now,&lt;br&gt;
&lt;u&gt;Instead of&lt;/u&gt;:&lt;br&gt;
policy_en.pdf&lt;br&gt;
policy_fr.pdf&lt;br&gt;
policy_es.pdf&lt;br&gt;
policy_de.pdf&lt;br&gt;
policy_hi.pdf&lt;br&gt;
&lt;u&gt;There can be a single&lt;/u&gt;:&lt;br&gt;
policy.pgs&lt;/p&gt;

&lt;p&gt;Costs reduced. Inefficiencies decreased. All through a single and simple app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F21cr81lp37y4ewr0o5ij.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F21cr81lp37y4ewr0o5ij.png" alt="View doc in translated languages" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;More about Pegasus and my experience&lt;/u&gt;&lt;/strong&gt;&lt;br&gt;
1) At first, Pegasus worked only for txt files. I later added features for it to work with docx files as well as pdf files. There were so many issues that arose while working with docx and pdf files. The reason for that is, unlike txt files, docx and pdf files have a structure and a layout. I tried few ways to ensure that the translations follow the actual layout as much as possible. Eventually I reached a satisfiable outcome for pdfs and docs too.&lt;br&gt;
2) I wanted to make PPTs work with Pegasus too, but due to the time constraint, I wasn't able to. Working with PPTs requires better ways to extract text and place them back while making sure the bg is not affected. Working with PPTs and other file formats is something that can be done in the future.&lt;br&gt;
3) Working with Hindi. Hindi characters weren't visible. I had to download another npm package that can be used to display devnagari script.&lt;br&gt;
4) Due to time constraints, I wasn't able to make dedicated download files (like exe for windows). But the repo is self sufficient to build and run the application. All the steps are in the readme.&lt;br&gt;
5) I wanted to try something new for demo video, so I created the demo video using AI generated clips + screen recordings.&lt;br&gt;
6) I have done most of the app building and testing on WSL. I did test the app on windows, but not on iOS.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Study Table: Task-focused environment</title>
      <dc:creator>Shiv Rai (S_RAI)</dc:creator>
      <pubDate>Sun, 01 Mar 2026 17:52:41 +0000</pubDate>
      <link>https://dev.to/rai_shiv/study-table-task-focused-environment-2j95</link>
      <guid>https://dev.to/rai_shiv/study-table-task-focused-environment-2j95</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/weekend-2026-02-28"&gt;DEV Weekend Challenge: Community&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Community
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;StudyTable&lt;/strong&gt; for students, developers, and builders who regularly participate in focused study or work sessions — especially people who learn independently or work on side projects.&lt;/p&gt;

&lt;p&gt;Many communities today (open-source contributors, students preparing for exams, hackathon participants, self-learners, etc.) struggle not with &lt;em&gt;starting&lt;/em&gt; work, but with maintaining structured, distraction-free focus.&lt;/p&gt;

&lt;p&gt;StudyTable is designed for anyone who values deep work and intentional learning.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;StudyTable&lt;/strong&gt; is a frontend-only web app that helps users run structured focus sessions.&lt;/p&gt;

&lt;p&gt;Instead of being just another timer, StudyTable treats work as a &lt;strong&gt;guided session&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Users create sessions with tasks with custom durations.&lt;/li&gt;
&lt;li&gt;Each task runs as a timed focus block.&lt;/li&gt;
&lt;li&gt;After completion, users intentionally transition into breaks or extend work time.&lt;/li&gt;
&lt;li&gt;Sessions generate time reports showing how time was actually spent on the work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The experience is designed to feel simple and calm — reducing decision fatigue while working.&lt;/p&gt;

&lt;p&gt;Core idea:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Most productivity apps track time.&lt;br&gt;
StudyTable helps users &lt;strong&gt;utilize time intentionally&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Website: &lt;a href="https://studytable-psi.vercel.app/" rel="noopener noreferrer"&gt;https://studytable-psi.vercel.app/&lt;/a&gt;&lt;br&gt;
Youtube: &lt;a href="https://youtu.be/dbjE8EMlAHI" rel="noopener noreferrer"&gt;https://youtu.be/dbjE8EMlAHI&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Github Repo: &lt;a href="https://github.com/ShivRaiGithub/studytable" rel="noopener noreferrer"&gt;https://github.com/ShivRaiGithub/studytable&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;StudyTable is intentionally built &lt;strong&gt;without a backend&lt;/strong&gt;, keeping the architecture lightweight and accessible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technologies Used
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js (App Router)&lt;/strong&gt; — application structure and routing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React&lt;/strong&gt; — UI and state management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TypeScript&lt;/strong&gt; — safer and maintainable code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tailwind CSS&lt;/strong&gt; — styling and layout&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Solo Member: Shiv Rai (S_RAI)&lt;br&gt;
Dev.to: &lt;a href="https://dev.to/rai_shiv"&gt;https://dev.to/rai_shiv&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Ouija Terminal - GitHub Copilot CLI Challenge</title>
      <dc:creator>Shiv Rai (S_RAI)</dc:creator>
      <pubDate>Sun, 15 Feb 2026 12:42:36 +0000</pubDate>
      <link>https://dev.to/rai_shiv/ouija-terminal-github-copilot-cli-challenge-3no9</link>
      <guid>https://dev.to/rai_shiv/ouija-terminal-github-copilot-cli-challenge-3no9</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-01-21"&gt;GitHub Copilot CLI Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;A fun little project built &lt;strong&gt;fully using Github Copilot CLI only&lt;/strong&gt;. &lt;br&gt;
&lt;u&gt;"Ouija Terminal"&lt;/u&gt;, a terminal which seems normal at first, but all interaction ultimately lead to the paranormal. &lt;br&gt;
There are various interactions you can do with the terminal through commands like saving name, changing theme of terminal, get current status, get time and date, etc. But each command changes it's behavior as you interact more.&lt;br&gt;
&lt;u&gt;Try it for yourself&lt;/u&gt;: &lt;a href="https://ouija-terminal.vercel.app/" rel="noopener noreferrer"&gt;https://ouija-terminal.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Demo&lt;/strong&gt;: &lt;a href="https://youtu.be/FMNh3W5Ccuw" rel="noopener noreferrer"&gt;https://youtu.be/FMNh3W5Ccuw&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Website&lt;/strong&gt;: &lt;a href="https://ouija-terminal.vercel.app/" rel="noopener noreferrer"&gt;https://ouija-terminal.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vibe coding video&lt;/strong&gt;: &lt;a href="https://youtu.be/LeKYyDMaXN0" rel="noopener noreferrer"&gt;https://youtu.be/LeKYyDMaXN0&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Images
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ft2op32by3lwc1oy5hwm1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ft2op32by3lwc1oy5hwm1.png" alt="Ouija Terminal" width="800" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fwkivnm845k42gobeb31f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fwkivnm845k42gobeb31f.png" alt="Ouija Terminal Interactions 1" width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fsmalfxy05fk45nhqmb11.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fsmalfxy05fk45nhqmb11.png" alt="Ouija Terminal Interactions 2" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  My Experience with GitHub Copilot CLI
&lt;/h2&gt;

&lt;p&gt;This was actually the &lt;strong&gt;first time I used an AI from CLI&lt;/strong&gt;. I haven't even used Claude Code before. I usually use Copilot Agent.&lt;br&gt;
Using CLI felt a little slower as compared to Copilot Agent on the file generation and editing part. But at the same time I never had to click "Continue" anywhere which usually appears when working with Agent.&lt;br&gt;
Also, there were different options available when executing a command which allowed you to set the permission to execute the commands for the entire CLI session which is a nice touch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Team Members
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Solo member&lt;/strong&gt;: Shiv Rai (S_RAI) &lt;a class="mentioned-user" href="https://dev.to/rai_shiv"&gt;@rai_shiv&lt;/a&gt; &lt;br&gt;
&lt;a href="https://dev.to/rai_shiv"&gt;https://dev.to/rai_shiv&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
      <category>cli</category>
      <category>githubcopilot</category>
    </item>
  </channel>
</rss>
