<?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>Forem: Justin Karneges</title>
    <description>The latest articles on Forem by Justin Karneges (@jkarneges).</description>
    <link>https://forem.com/jkarneges</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2897038%2F8fa2ff18-418e-4a0b-b9f6-479dc4523d73.jpg</url>
      <title>Forem: Justin Karneges</title>
      <link>https://forem.com/jkarneges</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jkarneges"/>
    <language>en</language>
    <item>
      <title>Announcing the Pub/Sub Compute app</title>
      <dc:creator>Justin Karneges</dc:creator>
      <pubDate>Wed, 26 Feb 2025 19:44:25 +0000</pubDate>
      <link>https://forem.com/fastly/announcing-the-pubsub-compute-app-35ki</link>
      <guid>https://forem.com/fastly/announcing-the-pubsub-compute-app-35ki</guid>
      <description>&lt;p&gt;We are excited to announce the &lt;a href="https://github.com/fastly/pubsub" rel="noopener noreferrer"&gt;Pub/Sub app&lt;/a&gt; for Fastly Compute, making it easy to push real-time updates to browsers and other devices. Messages are delivered via the Server-Sent Events or MQTT protocols. Check out &lt;a href="https://pubsub-test.glitch.me/" rel="noopener noreferrer"&gt;the demo&lt;/a&gt; to see it in action, and read on to learn how to set up your own instance in minutes!&lt;/p&gt;

&lt;p&gt;The Pub/Sub app is one of the first user-installable apps provided by Fastly that is production ready out of the box. It is not a template or starter kit that requires modification. Just install and go. Of course, since the code is open source, you are free to fork it and add your own functionality. We also welcome contributions.&lt;/p&gt;

&lt;p&gt;You may know that Fastly also offers powerful real-time messaging capability via &lt;a href="https://www.fastly.com/documentation/guides/concepts/real-time-messaging/fanout/" rel="noopener noreferrer"&gt;Fanout&lt;/a&gt;, however Fanout is designed for API operators with rigid requirements around messaging protocols, authentication, and storage. If you aren’t building or operating a push API and you simply want to send messages to browsers connected to your own website, then the Pub/Sub app is for you. Fun fact: the Pub/Sub app is built on top of Fanout!&lt;/p&gt;

&lt;p&gt;The Pub/Sub app is highly scalable and there are no hard limits. It supports millions of concurrent connections and channels, and there is no limit to the number of subscriptions a single channel can have. Even though the app is user-installable, there is nothing to manage. Fastly runs the app entirely serverlessly, worldwide.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;To get started, clone the repo and use the &lt;code&gt;fastly&lt;/code&gt; tool to deploy it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/fastly/pubsub.git
cd pubsub
fastly compute publish
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assuming the &lt;code&gt;fastly.toml&lt;/code&gt; file hasn't been modified, the above command will create a new Compute service and set up any related resources.&lt;/p&gt;

&lt;p&gt;After that, enable Fanout on the service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fastly products --enable=fanout
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add a backend called "self" to your service, for directing Fanout-managed requests back to the service itself. Replace &lt;code&gt;{DOMAIN}&lt;/code&gt; with the domain selected during deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fastly backend create \
  --name self \
  --address {DOMAIN} \
  --port 443 \
  --version latest --autoclone
fastly service-version activate --version latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Determine the ID of the "secrets" Secret Store:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fastly resource-link list --version latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for a block of output where the Resource Type is &lt;code&gt;secret-store&lt;/code&gt; and the Name is whatever name you gave to the "secrets" Secret Store. The Resource ID is the store's ID.&lt;/p&gt;

&lt;p&gt;Create a Fastly API token with the ability to publish Fanout messages. Do this by going to the Fastly management panel -&amp;gt; Accounts -&amp;gt; API tokens -&amp;gt; Personal tokens -&amp;gt; Create Token. Select Automation type, &lt;code&gt;purge_select&lt;/code&gt; scope, limited to the service, and never expiring, and click Create Token. Then save the token in the above store:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fastly secret-store-entry create \
  -s {STORE_ID} \
  --name publish-token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above command will prompt for the token value, which you can paste in.&lt;/p&gt;

&lt;p&gt;Congrats, you have a pub/sub service! Next, we'll discuss how to use it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;Messages can be sent and received over HTTP or MQTT, and access must be authorized using tokens. In this section, we'll discuss how to send messages with HTTP.&lt;/p&gt;

&lt;p&gt;First, you'll need a token signing key. Create one by sending a POST to the app's &lt;code&gt;/admin/keys&lt;/code&gt; endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl \
  -X POST \
  -H "Fastly-Key: $FASTLY_API_TOKEN" \
  https://{DOMAIN}/admin/keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The app will respond with a key ID and value. Note them in a safe place. The value is used for signing JWTs. The ID must be included in the &lt;code&gt;kid&lt;/code&gt; header field of the JWTs.&lt;/p&gt;

&lt;p&gt;Once you have a signing key, you can create authorization tokens for subscribers and publishers as needed. Below is an example using Python and the PyJWT library to create a token allowing access to a topic named "test". Replace &lt;code&gt;{KEY_ID}&lt;/code&gt; and &lt;code&gt;{KEY_VALUE}&lt;/code&gt; with your key ID and value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;exp&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x-fastly-read&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;test&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x-fastly-write&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;test&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{KEY_VALUE}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kid&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{KEY_ID}&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;Now that you have a token, you can subscribe a client. Here's an example using curl:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl \
  -H "Authorization: Bearer $TOKEN" \
  "https://{DOMAIN}/events?topic=test"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above command establishes a never-ending response body that the client can receive messages over.&lt;/p&gt;

&lt;p&gt;And here's how to publish a message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"text":"hello world"}'
  "https://{DOMAIN}/events?topic=test"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running the above command, the earlier curl should output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;event: message
data: {"text":"hello world"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For further details, including how to use the app with MQTT, see the &lt;a href="https://github.com/fastly/pubsub/blob/main/README.md" rel="noopener noreferrer"&gt;README&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Questions/Comments?
&lt;/h2&gt;

&lt;p&gt;Feel free to file issues on the &lt;a href="https://github.com/fastly/pubsub" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt; for specific code related bugs or features, or chat with us on the &lt;a href="https://community.fastly.com/t/announcing-fastlys-official-pubsub-application/3876" rel="noopener noreferrer"&gt;Fastly Community Forum&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>pubsub</category>
      <category>serverless</category>
      <category>rust</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
