<?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: Rawley Fowler</title>
    <description>The latest articles on Forem by Rawley Fowler (@rawleyfowler).</description>
    <link>https://forem.com/rawleyfowler</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%2F717877%2Fac676d31-dbad-49eb-aa5c-08eac25e1481.jpeg</url>
      <title>Forem: Rawley Fowler</title>
      <link>https://forem.com/rawleyfowler</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/rawleyfowler"/>
    <language>en</language>
    <item>
      <title>Monitoring a Plack Application with SlapbirdAPM</title>
      <dc:creator>Rawley Fowler</dc:creator>
      <pubDate>Fri, 16 May 2025 14:22:42 +0000</pubDate>
      <link>https://forem.com/rawleyfowler/monitoring-a-plack-application-with-slapbirdapm-1mh</link>
      <guid>https://forem.com/rawleyfowler/monitoring-a-plack-application-with-slapbirdapm-1mh</guid>
      <description>&lt;p&gt;&lt;a href="https://www.slapbirdapm.com" rel="noopener noreferrer"&gt;SlapbirdAPM&lt;/a&gt; is a free and open-source application performance monitoring (APM) platform specifically designed for Perl web applications. It provides developers with comprehensive observability tools to monitor and optimize their applications' performance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.slapbirdapm.com" rel="noopener noreferrer"&gt;SlapbirdAPM&lt;/a&gt; is easily installed on your Plack application, here is a minimal example, using a Dancer2 application:&lt;/p&gt;

&lt;p&gt;Install with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cpan -I SlapbirdAPM::Agent::Plack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env perl&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nv"&gt;Dancer2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;Plack::&lt;/span&gt;&lt;span class="nv"&gt;Builder&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nv"&gt;get&lt;/span&gt; &lt;span class="p"&gt;'&lt;/span&gt;&lt;span class="s1"&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="k"&gt;sub &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello World!&lt;/span&gt;&lt;span class="p"&gt;';&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nv"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;enable&lt;/span&gt; &lt;span class="p"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SlapbirdAPM&lt;/span&gt;&lt;span class="p"&gt;';&lt;/span&gt;
    &lt;span class="nv"&gt;app&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;Now, you can create an account on &lt;a href="https://www.slapbirdapm.com" rel="noopener noreferrer"&gt;SlapbirdAPM&lt;/a&gt;, and create your application.&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%2Ffi5dhn24440ucs5g5nd3.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%2Ffi5dhn24440ucs5g5nd3.png" alt="New Application" width="590" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, simply copy the API key output and, add it to your application via the &lt;code&gt;SLAPBIRDAPM_API_KEY&lt;/code&gt; environment variable. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;SLAPBIRDAPM_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;API-KEY&amp;gt; plackup app.pl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or, you can pass your key in to the middleware:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="nv"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;enable&lt;/span&gt; &lt;span class="p"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SlapbirdAPM&lt;/span&gt;&lt;span class="p"&gt;',&lt;/span&gt; &lt;span class="s"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;YOUR&lt;/span&gt; &lt;span class="nv"&gt;API&lt;/span&gt; &lt;span class="nv"&gt;KEY&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&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 when you navigate to &lt;code&gt;/&lt;/code&gt;, you will see it logged in your &lt;a href="https://www.slapbirdapm.com" rel="noopener noreferrer"&gt;Slapbird&lt;/a&gt; dashboard!&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%2Fmeus9mrhpyc5tglqakbd.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%2Fmeus9mrhpyc5tglqakbd.png" alt="Dashboard" width="800" height="433"&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%2Fv5stuac3uebyxgopcko5.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%2Fv5stuac3uebyxgopcko5.png" alt="Individual transaction" width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.slapbirdapm.com" rel="noopener noreferrer"&gt;SlapbirdAPM&lt;/a&gt; also supports DBI, meaning you can trace your queries, let's edit our application to include a few DBI queries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env perl&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nv"&gt;Dancer2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nv"&gt;DBI&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;Plack::&lt;/span&gt;&lt;span class="nv"&gt;Builder&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$dbh&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;DBI&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dbi:SQLite:dbname=database.db&lt;/span&gt;&lt;span class="p"&gt;',&lt;/span&gt; &lt;span class="p"&gt;'',&lt;/span&gt; &lt;span class="p"&gt;''&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$dbh&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;create table if not exists users (id integer primary key, name varchar)&lt;/span&gt;&lt;span class="p"&gt;');&lt;/span&gt;

&lt;span class="nv"&gt;get&lt;/span&gt; &lt;span class="p"&gt;'&lt;/span&gt;&lt;span class="s1"&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="k"&gt;sub &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;send_as&lt;/span&gt; &lt;span class="s"&gt;html&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello World!&lt;/span&gt;&lt;span class="p"&gt;';&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nv"&gt;get&lt;/span&gt; &lt;span class="p"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users/:id&lt;/span&gt;&lt;span class="p"&gt;'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;sub &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;route_parameters&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;get&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="p"&gt;');&lt;/span&gt;
    &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
        &lt;span class="nv"&gt;$dbh&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;selectall_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="p"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;select * from users where id = ?&lt;/span&gt;&lt;span class="p"&gt;',&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;Slice&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nv"&gt;$user_id&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;send_as&lt;/span&gt; &lt;span class="s"&gt;JSON&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nv"&gt;post&lt;/span&gt; &lt;span class="p"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users&lt;/span&gt;&lt;span class="p"&gt;'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;sub &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$user_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;body_parameters&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;get&lt;/span&gt;&lt;span class="p"&gt;('&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="p"&gt;');&lt;/span&gt;
    &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="nv"&gt;$dbh&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;selectall_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;insert into users(name) values ( ? ) returning id, name&lt;/span&gt;&lt;span class="p"&gt;',&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;Slice&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nv"&gt;$user_name&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;send_as&lt;/span&gt; &lt;span class="s"&gt;JSON&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nv"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;enable&lt;/span&gt; &lt;span class="p"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SlapbirdAPM&lt;/span&gt;&lt;span class="p"&gt;';&lt;/span&gt;
    &lt;span class="nv"&gt;app&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;Now we can use cURL to add data to our database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'name=bob'&lt;/span&gt; http://127.0.0.1:5000/users
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, if we go back into Slapbird, we can view our timings for our queries:&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%2F0w12kkrcamirlqobipr0.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%2F0w12kkrcamirlqobipr0.png" alt="Image description" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This just breaks the surface of what is possible using &lt;a href="https://www.slapbirdapm.com" rel="noopener noreferrer"&gt;SlapbirdAPM&lt;/a&gt;. You can also, generate reports, perform health-checks, and get notified if your application is creating too many 5XX responses.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>perl</category>
      <category>observability</category>
      <category>monitoring</category>
      <category>plack</category>
    </item>
    <item>
      <title>Introducing Humming-Bird v3</title>
      <dc:creator>Rawley Fowler</dc:creator>
      <pubDate>Wed, 08 Nov 2023 01:41:51 +0000</pubDate>
      <link>https://forem.com/rawleyfowler/introducing-humming-bird-v3-3eni</link>
      <guid>https://forem.com/rawleyfowler/introducing-humming-bird-v3-3eni</guid>
      <description>&lt;p&gt;Hey folks! It's been a while!&lt;/p&gt;

&lt;p&gt;I've been busy, but I haven't forgotten about Humming-Bird. Actually I've been quite busy trying to figure out Web-Sockets, and swappable back-ends for &lt;a href="https://github.com/rawleyfowler/Humming-Bird" rel="noopener noreferrer"&gt;Humming-Bird&lt;/a&gt;, features requested by many!&lt;/p&gt;

&lt;p&gt;Web-Sockets have been put on the back-burner for a bit, but swappable back-ends, and many bug-fixes have been completed leading to a new version bump.&lt;/p&gt;

&lt;p&gt;A lot has changed, and I'm excited to see what sort of back-ends the community may come up with.&lt;/p&gt;

&lt;p&gt;To implement a Humming-Bird back-end, simply write a class that &lt;code&gt;does Humming-Bird::Backend;&lt;/code&gt;, and implement the listen routine, with a single argument of a function that takes a &lt;code&gt;Humming-Bird::Glue::Request&lt;/code&gt; and returns a &lt;code&gt;Humming-Bird::Glue::Response&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use Humming-Bird::Glue;

unit role Humming-Bird::Backend::MyBackend;

method listen(&amp;amp;handler) {
    my $request  = Humming-Bird::Glue::Request.decode(somehow-get-http-request());
    my $response = &amp;amp;handler($request);
    somehow-send-http-response($response.encode);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now in your Humming-Bird app add the following to the listen clause:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use Humming-Bird::Core;

get('/', -&amp;gt; $request, $response {
    $response.html("Hello World!");
});

listen(:backend(Humming-Bird::Backend::MyBackend));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thanks for reading, Raku rocks!&lt;/p&gt;

</description>
      <category>raku</category>
      <category>rakulang</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Functional Programming with Raku</title>
      <dc:creator>Rawley Fowler</dc:creator>
      <pubDate>Sun, 23 Apr 2023 18:36:52 +0000</pubDate>
      <link>https://forem.com/rawleyfowler/functional-programming-with-raku-9ib</link>
      <guid>https://forem.com/rawleyfowler/functional-programming-with-raku-9ib</guid>
      <description>&lt;p&gt;Raku is a great language for functional programming, it has support for anonymous functions (blocks), partial application via &lt;code&gt;assuming&lt;/code&gt;, and much more.&lt;/p&gt;

&lt;p&gt;In this post I hope to outline how I use Raku as a functional (object-oriented) programming language similar to how I'd write a language like Scala.&lt;/p&gt;

&lt;h2&gt;
  
  
  The compose operator
&lt;/h2&gt;

&lt;p&gt;In Raku &lt;code&gt;o&lt;/code&gt; is an operator (a binary function). Which means we can compose two functions together to create a new one. This lets us build really cool abstractions over our functions. For example we can use it to create functions with hidden side-effects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my $logger = -&amp;gt; $m { say $m; $m };
my $add-five = -&amp;gt; $x { $x + 5 };
my $add-five-and-log = $add-five o $logger;

say $add-five-and-log(25); # Prints 25, then prints 30
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that the composition occurs backwards in a way, &lt;code&gt;$add-five o $logger&lt;/code&gt; is equivalent to &lt;code&gt;-&amp;gt; x { $add-five($logger(x)) }&lt;/code&gt;. Pretty neat right!&lt;/p&gt;

&lt;p&gt;This also allows us to simply reduce arrays of functions into a single function, in the Humming-Bird source-code, you can see that in practice for "advice" the end-of-routing hooks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;method !add-route(Route:D $route, HTTPMethod:D $method --&amp;gt; Route:D) {
        my &amp;amp;advice = [o] @!advice;
        my &amp;amp;cb = $route.callback;
        my $r = $route.clone(path =&amp;gt; $!root ~ $route.path,
                             middlewares =&amp;gt; [|@!middlewares, |$route.middlewares],
                             callback =&amp;gt; { &amp;amp;advice(&amp;amp;cb($^a, $^b)) });
        @!routes.push: $r;
        delegate-route($r, $method);
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This method on the Router class adds a route object to the context of the application, you'll notice the first line of the method, we apply &lt;code&gt;o&lt;/code&gt; in a reduction to produce a single function from the advice array. &lt;code&gt;@!advice&lt;/code&gt; being all the advice on this router. Advice are simply functions that take a response, and return a response. So you can imagine how the composition operator is layering all of them together like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-&amp;gt; x { advice-four(advice-three(advice-two(advice-one(x)))) }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, to call the advice all we have to do is pass a response to the composition, and it will handle the rest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Assuming
&lt;/h2&gt;

&lt;p&gt;Assuming is a method derived from the &lt;code&gt;Code&lt;/code&gt; class, and it allows us to perform partial-application on a function. Partial application is very simple, it means to call a function with less arguments than it requires, which in-turn returns a new function that contains the parameters you've already supplied. For example if we have an &lt;code&gt;add&lt;/code&gt; function that takes two numbers, we could partially apply it like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my $add = -&amp;gt; $x, $y { $x + $y };

my $add-five = $add.assuming(5);

say $add-five(10); # prints 15
say $add-five(5); # prints 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result of calling &lt;code&gt;.assuming(5)&lt;/code&gt; on the &lt;code&gt;add&lt;/code&gt; function is a new function that looks like: &lt;code&gt;-&amp;gt; $y { 5 + $y }&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is a really neat feature that lets us create what I like to call 'stateless-state', meaning we can add state to our functions without actually exposing it to the consumer of the function.&lt;/p&gt;

&lt;p&gt;A fairly complicated, yet elegant example of using &lt;code&gt;.assuming&lt;/code&gt; in the wild is Humming-Birds middleware system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my &amp;amp;composition = @!middlewares.map({ .assuming($req, $res) }).reduce(-&amp;gt; &amp;amp;a, &amp;amp;b { &amp;amp;a({ &amp;amp;b }) });
&amp;amp;composition(&amp;amp;!callback.assuming($req, $res))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have to map all middleware to partially-apply the request and response objects that will be used throughout the request chain, then reduce to a single function that will take another function. Then finally, call the composition with the callback provided by the user. This is what allows middleware to have the &lt;code&gt;$request, $response, &amp;amp;next&lt;/code&gt; parameters. Calling &lt;code&gt;&amp;amp;next()&lt;/code&gt; is simply calling the next partially applied function in the chain!&lt;/p&gt;

&lt;h2&gt;
  
  
  Anonymous functions (blocks)
&lt;/h2&gt;

&lt;p&gt;Raku is one of the only languages I know that has more than one way to declare an anonymous function (aka lambda). In Raku we have pointy-blocks (my favorite), normal blocks, &lt;a href="https://docs.raku.org/type/WhateverCode.html" rel="noopener noreferrer"&gt;WhateverCodes&lt;/a&gt; and anonymous sub-routines.&lt;/p&gt;

&lt;p&gt;Typically, in my experience, you'll be fine with a normal block for most things, unless you want to strictly define your parameters, then it's best to use a pointy-block or anonymous sub-routine. If you need to explicitly return i.e short-circuit you'll probably want to use an anonymous sub, otherwise a pointy block will do.&lt;/p&gt;

&lt;p&gt;Here's the same function &lt;code&gt;add&lt;/code&gt; written using each type of block:&lt;/p&gt;

&lt;h5&gt;
  
  
  Normal block
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my &amp;amp;add = { $^a + $^b };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Whatever Code
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my &amp;amp;add = * + *;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Pointy block
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my &amp;amp;add = -&amp;gt; $a, $b { $a + $b };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Anonymous sub
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my &amp;amp;add = sub ($a, $b) { $a + $b };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use the &lt;code&gt;&amp;amp;&lt;/code&gt; sigil to declare functions stored in variables in a more 'Raku-ish' way, this will tell other developers that the variable is a &lt;code&gt;Callable&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can pass these anonymous functions to other functions, this is used fairly-extensively in the realm of reactive-programming. &lt;code&gt;whenever&lt;/code&gt; registers a callback with an anonymous function (block or pointy block):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;react {
    whenever Supply.interval(1) -&amp;gt; $second {
        say 'Current second: $second';
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Raku's standard library, for example, a for loop takes a block or point block as an argument, you probably never thought about it like that before right?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for [1,2,3,4] -&amp;gt; $x { say $x }; # That block can be thought of as a lambda!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Humming-Bird when you declare routes like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get('/', -&amp;gt; $request, $response {
   $response.write('Hello World!');
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the background that block is taken in by the &lt;code&gt;get&lt;/code&gt; function then registered as what to call when the router receives a request.&lt;/p&gt;

&lt;p&gt;Overall, Raku has some really interesting and usable functional patterns. I personally am a big fan of partial application and the composition operator. It is really fun as-well!&lt;/p&gt;

&lt;p&gt;To finish off I'd like to leave a fun example, see if you can predict the result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;([o] [-&amp;gt; $a { $a + 1 }, -&amp;gt; $a { $a + 1 }])(2).say
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take care! Raku rocks!&lt;/p&gt;

</description>
      <category>raku</category>
      <category>functional</category>
    </item>
    <item>
      <title>How I Structure my Humming-Bird Projects</title>
      <dc:creator>Rawley Fowler</dc:creator>
      <pubDate>Sun, 19 Mar 2023 23:45:30 +0000</pubDate>
      <link>https://forem.com/rawleyfowler/how-i-like-to-structure-my-humming-bird-projects-50nm</link>
      <guid>https://forem.com/rawleyfowler/how-i-like-to-structure-my-humming-bird-projects-50nm</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/rawleyfowler/Humming-Bird" rel="noopener noreferrer"&gt;Humming-Bird&lt;/a&gt; is a very unopinionated web framework. It allows the developer to structure their projects however they like. As the creator of Humming-Bird I can openly say that this was on purpose, and takes after a few other popular frameworks.&lt;/p&gt;

&lt;p&gt;Though this was on purpose, it can seem daunting, especially to people new to the Raku ecosystem, or new to designing web-applications in general. I hope to underline the few structures I have employed to making sure my application makes sense from a developers point of view, but also from a Raku point of view.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Single File Service
&lt;/h2&gt;

&lt;p&gt;If you find that your service will be small, you may want to consider building your system in a single-file. This is done very simply with a structure like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;App-MyService/
    ├── bin/
    │   └── my-service
    ├── lib/
    │   └── App/
    │       └── MyService.rakumod
    ├── META6.json
    └── Dockerfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your &lt;code&gt;META6.json&lt;/code&gt; you'll have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
    "provides": {
        "App::MyService": "lib/App/MyService.rakumod"
    }
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then in your &lt;code&gt;bin&lt;/code&gt; file you'll want to import your service, and Humming-Bird, something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use Humming-Bird::Core;
use App::MyService;

listen(1234);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is important that you import &lt;code&gt;App::MyService&lt;/code&gt; after &lt;code&gt;Humming-Bird::Core&lt;/code&gt; to avoid having some weird side-effects with route declarations in your service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Model-View-Controller
&lt;/h2&gt;

&lt;p&gt;Some web-apps would prefer to be elevated above the status of service, and would prefer to have a dynamic UI. This is typically done with the &lt;code&gt;Model-View-Controller&lt;/code&gt; or &lt;code&gt;MVC&lt;/code&gt; architecture. In a typical MVC application you separate concerns between the model, the view, and the controller by keeping them in separate name-spaces or folders.&lt;/p&gt;

&lt;p&gt;With Humming-Bird, nothing really changes except that your &lt;code&gt;views&lt;/code&gt; probably don't have to be individual Raku modules. I like to structure such applications like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-service/
    ├── templates/
    │   ├── foo.mustache
    │   └── bar.mustache
    ├── bin/
    │   └── my-service
    ├── lib/
    │   └── App/
    │       ├── MyService/
    │       │   ├── Controller/
    │       │   │   ├── Foo.rakumod
    │       │   │   └── Bar.rakumod
    │       │   └── Model/
    │       │       ├── User.rakumod
    │       │       ├── Friend.rakumod
    │       │       └── Post.rakumod
    │       └── MyService.rakumod
    ├── META6.json
    └── Dockerfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll still want the same &lt;code&gt;use&lt;/code&gt; statements in your &lt;code&gt;bin&lt;/code&gt; file, but this time you'll have to do a provide in your &lt;code&gt;META6&lt;/code&gt; file for each of the nested modules.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
"provides": {
    "App::MyService": "lib/App/MyService.rakumod",
    "App::MyService::Controller::Foo": "lib/App/MyService/Controller/Foo.rakumod"
    ...
},
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can layer your code nicely, having the controllers call to the models to get data, and then rendering pages based on your templates. In this example I used &lt;code&gt;Template::Mustache&lt;/code&gt; by &lt;a href="https://github.com/softmoth/raku-Template-Mustache" rel="noopener noreferrer"&gt;softmoth&lt;/a&gt;, but you can also user other templating languages like &lt;code&gt;Template6&lt;/code&gt; by the &lt;a href="https://github.com/raku-community-modules/Template6" rel="noopener noreferrer"&gt;Raku Community&lt;/a&gt;, or &lt;code&gt;RyML&lt;/code&gt; by the dashing &lt;a href="https://github.com/tony-o/ryml" rel="noopener noreferrer"&gt;tony-o&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: this is following an "Active-Record" approach to database management, where the sub-class of a type handles &lt;code&gt;Repository&lt;/code&gt; type actions. You can use either. If you are looking for an "Active-Record" style database manager ORM thing, you can use &lt;a href="https://github.com/FCO/Red" rel="noopener noreferrer"&gt;Red&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Microservice
&lt;/h2&gt;

&lt;p&gt;With a microservice I'm typically more focused around data and its flow, because of this, I adapt my single-file structure to also have a &lt;code&gt;Repository&lt;/code&gt; section, allowing me to nicely package my database interactions. I also like to have a &lt;code&gt;Queue&lt;/code&gt; or &lt;code&gt;Communication&lt;/code&gt; module that handles talking with other service if I need to. This typically includes talking to queues, or establishing other &lt;code&gt;UDP&lt;/code&gt; or &lt;code&gt;TCP&lt;/code&gt; connections.&lt;/p&gt;

&lt;p&gt;With Microservices I prefer the more fine-grained &lt;code&gt;Repository&lt;/code&gt; approach where I can hone in on writing fast SQL vs the "Active-Record" approach that something like &lt;a href="https://github.com/FCO/Red" rel="noopener noreferrer"&gt;Red&lt;/a&gt; gives you. Because of this, I typically use &lt;a href="https://github.com/raku-community-modules/DBIish" rel="noopener noreferrer"&gt;DBIish&lt;/a&gt; for microservices.&lt;/p&gt;

&lt;p&gt;My simple microservice structure typically 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;my-service/
    ├── bin/
    │   └── my-service
    ├── lib/
    │   └── App/
    │       ├── MyService/
    │       │   ├── Communication/
    │       │   │   ├── Queue.rakumod
    │       │   │   └── Upstream.rakumod
    │       │   ├── Repostiory/
    │       │   │   ├── Foo.rakumod
    │       │   │   └── Bar.rakumod
    │       │   └── Controller/
    │       │       ├── Foo.rakumod
    │       │       └── Bar.rakumod
    │       └── MyService.rakumod
    ├── META6.json
    └── Dockerfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This blog post was fairly erratic, but I hope it demystified a little bit about project structure using Humming-Bird. I'm currently writing a small &lt;code&gt;MVC&lt;/code&gt; example for Humming-Bird, make sure to check the &lt;a href="https://github.com/rawleyfowler/Humming-Bird/tree/main/examples" rel="noopener noreferrer"&gt;examples directory&lt;/a&gt; to see some existing apps, and check back soon to see the full-fledged &lt;code&gt;MVC&lt;/code&gt; example. &lt;/p&gt;

&lt;p&gt;Thanks for reading, Raku rocks!&lt;/p&gt;

</description>
      <category>raku</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Practical Monads with Raku and Monad::Result</title>
      <dc:creator>Rawley Fowler</dc:creator>
      <pubDate>Sun, 12 Mar 2023 16:21:08 +0000</pubDate>
      <link>https://forem.com/rawleyfowler/practical-monads-with-raku-and-monadresult-8c8</link>
      <guid>https://forem.com/rawleyfowler/practical-monads-with-raku-and-monadresult-8c8</guid>
      <description>&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Monad_(functional_programming)" rel="noopener noreferrer"&gt;Monads&lt;/a&gt; are a great tool in every programming language, they provide a simple way to hide side-effects in your code, and in languages that allow even the slightest amount of pattern matching, they enable "Railroad Oriented" programming.&lt;/p&gt;

&lt;p&gt;Thankfully, Raku has &lt;code&gt;given&lt;/code&gt; which enables us to perform simple pattern matching, and with it's dependent-type system we can easily define our own Monads. I wrote &lt;a href="https://github.com/rawleyfowler/Monad-Result" rel="noopener noreferrer"&gt;Monad::Result&lt;/a&gt; a month or two ago, and I have used it in almost all of my Raku projects since.&lt;/p&gt;

&lt;p&gt;Simply install &lt;code&gt;Monad::Result&lt;/code&gt; with zef:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;zef install Monad-Result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Monad::Result&lt;/code&gt; is an extremely simple package that is designed to allow programmers to easily hide exceptions within a container, forcing the caller to evaluate both possible scenarios of the call. This is particularly useful when dealing with IO, Network calls, Databases, Asynchronous callbacks, etc. Basically anything with a well-defined side-effect. If you don't know what a side-effect is, it's basically the "sad-pass" of an operation. So in the case of an HTTP request, it may fail due to a number of reasons, it's failure would be it's side-effect. What's nice about using a Monad to represent this, is we can hide all the ugliness behind an easily consumed interface, whereas with exceptions it becomes quite cumbersome.&lt;/p&gt;

&lt;h2&gt;
  
  
  Abstracting away exceptions
&lt;/h2&gt;

&lt;p&gt;The most common way I find myself using &lt;code&gt;Monad::Result&lt;/code&gt; is with exceptions. Since I can't specify the exceptions in the type-signature, or return type of a function, I find they often go uncaught and lead to some gross bugs. But, with &lt;code&gt;Monad::Result&lt;/code&gt; as the return type, the developer calling the code can infer "hey, this code might fail".&lt;/p&gt;

&lt;p&gt;Here is a simple wrapper around &lt;code&gt;DBIish&lt;/code&gt; I typically use to hide exceptions from the caller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use DBIish;
use Monad::Result :subs;

my $db = DBIish.connect('SQLite', :database&amp;lt;foo.db&amp;gt;);

sub exec-sql(Str:D $sql, *@args --&amp;gt; Monad::Result:D) is export {
    CATCH {
        default {
            return error($_);
        }
    }

    my $stmt = db.prepare($sql); 
    ok($stmt.execute(|@args).allrows(:array-of-hash));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's break down what's going on inside the &lt;code&gt;exec-sql&lt;/code&gt; sub-routine.&lt;/p&gt;

&lt;p&gt;Since DBIish will fire an exception if something goes wrong, we catch it in the &lt;code&gt;CATCH&lt;/code&gt;, it will catch any exception and return it as a &lt;code&gt;Monad::Result{+Monad::Result::Error}&lt;/code&gt; basically a result of error, and obviously, if it succeeds, then the sub-routing will return a &lt;code&gt;Monad::Result{+Monad::Result::Ok}&lt;/code&gt;, meaning it succeeded.&lt;/p&gt;

&lt;p&gt;So if we wanted to use our new &lt;code&gt;exec-sql&lt;/code&gt; sub-routing downstream we'll know explicitly that this call can, and will fail. So, we can do some pattern-matching with &lt;code&gt;given&lt;/code&gt; to make sure our code is super safe!&lt;/p&gt;

&lt;p&gt;Here is how you typically see a &lt;code&gt;Monad::Result&lt;/code&gt; consumed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;given exec-sql('SELECT * FROM users') {
    when Monad::Result::Ok:D {
        my @users = $_.value; # safe to do so because we know we're Ok!
        say "Got all users! @users";
    }
    when Monad::Result::Error:D {
        my $exception = $_.error;
        warn "Failed to get all users, oh no! Had this error $exception";
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We simply match against the two possibilities for a &lt;code&gt;Monad::Result&lt;/code&gt;, and our code remains completely safe.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bind and Map
&lt;/h2&gt;

&lt;p&gt;Now you're probably wondering "How the heck is this practical, what if I have to combine a hundred side-effect calls? This will become a mess!" And you'd be right, especially if Raku was a &lt;a href="https://go.dev/learn/" rel="noopener noreferrer"&gt;bad language&lt;/a&gt; that didn't allow user defined operators. (Just joking Go isn't bad, but Raku is simply better :^). Because of this, we can use the &lt;code&gt;&amp;gt;&amp;gt;=:&lt;/code&gt; (Bind) and &lt;code&gt;&amp;gt;&amp;gt;=?&lt;/code&gt; (Map) operators respectfully to manage our Monad.&lt;/p&gt;

&lt;p&gt;These operators are super simple, all they do is take a &lt;code&gt;Monad::Result&lt;/code&gt; on the left and a &lt;code&gt;Callable&lt;/code&gt; on the right. Then, if the &lt;code&gt;Monad::Result&lt;/code&gt; on the left is Ok, it will call the &lt;code&gt;Callable&lt;/code&gt; with underlying value of the result. If the result isn't Ok, we just pass the error along. This allows for beautifully chained side-effects without the possibility of an exception blowing up on you (assuming you only call code that can't cause an exception). If you want to use another exception causing routing within a Bind or Map operation you'll have to write a wrapper that returns a &lt;code&gt;Monad::Result&lt;/code&gt; instead.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exec-sql('SELECT * FROM users') &amp;gt;&amp;gt;=: { say @^a; ok(@^a.map(*.&amp;lt;name&amp;gt;)) };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code will select all users from our database, if it succeeds we'll print to the console all of the users, and map the list to just their name.&lt;/p&gt;

&lt;p&gt;We could also use the &lt;code&gt;&amp;gt;&amp;gt;=?&lt;/code&gt; (Map) operation to avoid having to wrap our return with &lt;code&gt;ok&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exec-sql('SELECT * FROM users') &amp;gt;&amp;gt;=? { say @^a; @^a.map(*.&amp;lt;name&amp;gt;) };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, if you're not really a Functional Programmer, these operators might be a little scary. Instead, if you wish, you can use the OO versions like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exec-sql('SELECT * FROM users').bind({ say @^a; ok(@^a.map(*.&amp;lt;name&amp;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 plaintext"&gt;&lt;code&gt;exec-sql('SELECT * FROM users').map({ say @^a; @^a.map(*.&amp;lt;name&amp;gt;) });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Personally I like to use the OO version if I have to Bind or Map more than 3 times in a row. &lt;/p&gt;

&lt;h2&gt;
  
  
  Monads in the wild
&lt;/h2&gt;

&lt;p&gt;Here are some snippets of some production code that uses &lt;code&gt;Monad::Result&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Find-one SQL
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sub find-one($query, *@args) {
    exec-sql($query, |@args) &amp;gt;&amp;gt;=: -&amp;gt; @rows { @rows.elems == 1 ?? ok(@rows[0]) !! error(@rows) };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a simple wrapper around the earlier &lt;code&gt;exec-sql&lt;/code&gt; routine that binds to it's result and if it isn't exactly one element it will return an Error result.&lt;/p&gt;

&lt;h4&gt;
  
  
  HTTP chaining
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This code isn't in production yet, but it's a part of a large project I'm working on :)&lt;/p&gt;

&lt;p&gt;Another cool use for &lt;code&gt;Monad::Result&lt;/code&gt; is for HTTP requests, sometimes we need to chain them together, here is a simple example of chaining 3 HTTP requests that rely on each-other:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;auth-client.get-user-roles($id)
           .bind({ 'ADMIN' (elem) @^a ?? user-client.get-user($id) !! error('User is not an admin') })
           .bind({ dashboard-client.find-dashboard-by-user-id(@^a&amp;lt;id&amp;gt;) });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, &lt;code&gt;auth-client&lt;/code&gt;, &lt;code&gt;user-client&lt;/code&gt;, and &lt;code&gt;dashboard-client&lt;/code&gt;, are all wrappers around &lt;code&gt;Cro::HTTP::Client&lt;/code&gt; that perform HTTP requests to different services. All of the end-points are abstracted by a function and return a &lt;code&gt;Result::Monad&lt;/code&gt;, allowing the developers consuming them to simply chain them.&lt;/p&gt;

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

&lt;p&gt;&lt;code&gt;Monad::Result&lt;/code&gt; allows us to very concisely and elegantly deal with real-world side-effects. You can use them to simply chain side-effect reliant code without having to write a huge &lt;code&gt;CATCH&lt;/code&gt; block, and they also give the developer consuming our code the chance to realize that the code may return an Error.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/rawleyfowler/Monad-Result" rel="noopener noreferrer"&gt;Monad::Result&lt;/a&gt; is not the only monad in the Raku ecosystem, there is also &lt;a href="https://github.com/masukomi/Definitely" rel="noopener noreferrer"&gt;Definitely&lt;/a&gt; by Kay Rhodes (aka Masukomi) which provides a very nice "optional" type, that can fill a similar role to &lt;code&gt;Monad::Result&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading, Raku Rocks!&lt;/p&gt;

</description>
      <category>raku</category>
      <category>monad</category>
    </item>
    <item>
      <title>Writing a Database backed Micro-service with Raku and Humming-Bird</title>
      <dc:creator>Rawley Fowler</dc:creator>
      <pubDate>Sun, 05 Mar 2023 18:13:53 +0000</pubDate>
      <link>https://forem.com/rawleyfowler/writing-micro-services-with-raku-and-humming-bird-59k4</link>
      <guid>https://forem.com/rawleyfowler/writing-micro-services-with-raku-and-humming-bird-59k4</guid>
      <description>&lt;p&gt;Earlier this year I built a web-application framework for Raku called &lt;a href="https://github.com/rawleyfowler/Humming-Bird" rel="noopener noreferrer"&gt;Humming-Bird&lt;/a&gt;, it's come a long way since it's humble beginnings. In this post I'd like to outline how I use Humming-Bird to build fast, reliable, cloud-native services.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting set up
&lt;/h2&gt;

&lt;p&gt;To begin, you'll want to make sure that you have Raku installed, I recommend using &lt;a href="https://rakubrew.org/" rel="noopener noreferrer"&gt;Rakubrew&lt;/a&gt;. Then we'll want to install &lt;a href="https://github.com/ugexe/zef" rel="noopener noreferrer"&gt;Zef&lt;/a&gt;, if you're new to Raku, &lt;a href="https://github.com/ugexe/zef" rel="noopener noreferrer"&gt;Zef&lt;/a&gt; is basically just NPM or CPAN for Raku, it's written by the fabulous Ugexe and is the default package manager people use with Raku. If you installed Raku with &lt;code&gt;rakubrew download&lt;/code&gt;, you should already have it installed. If not, you can do &lt;code&gt;rakubrew build-zef&lt;/code&gt; to install it for your current Raku install.&lt;/p&gt;

&lt;p&gt;Finally, we'll want to install Humming-Bird, we can do this simply by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;zef &lt;span class="nb"&gt;install &lt;/span&gt;Humming-Bird
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will pull the latest stable version of Humming-Bird.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hello World
&lt;/h2&gt;

&lt;p&gt;Now that we've installed all of the pre-requisites let's write a simple "Hello World" web application. Humming-Bird is really simple so there isn't much to it!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use Humming-Bird::Core;

get('/', -&amp;gt; $request, $response {
    $response.html('&amp;lt;h1&amp;gt;Hello World!&amp;lt;/h1&amp;gt;');
});

listen(8080);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if we save this script as &lt;code&gt;app.raku&lt;/code&gt; then run it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;raku app.raku
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can navigate to &lt;code&gt;http://localhost:8080&lt;/code&gt; and we should see:&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%2F1d1e2aea3a5nie1syqlh.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%2F1d1e2aea3a5nie1syqlh.png" alt="Hello World" width="240" height="51"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's break down what's going on here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use Humming-Bird::Core;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Imports all of the exported members of Humming-Bird. This includes the functionality to allow creating routes, and to start the server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get('/', -&amp;gt; $request, $response {
    $response.html('&amp;lt;h1&amp;gt;Hello World!&amp;lt;/h1&amp;gt;');
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We register a GET route on '/' and hookup a block, AKA anonymous function, AKA lambda, to handle it. This lambda must take a request, and a response, and returns a response. All of the methods provided by the response object implicitly return itself so it makes it easy to chain and return. Also, the last evaluated expression will become the return of the lambda.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;listen(8080);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Starts a &lt;code&gt;Humming-Bird::HTTPServer&lt;/code&gt; on port 8080.&lt;/p&gt;

&lt;h2&gt;
  
  
  Designing our service
&lt;/h2&gt;

&lt;p&gt;Now that everything is setup and working. Let's get to designing our service. Our requirements are to design a service that provides the following end-points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GET&lt;/strong&gt; '/users': Returns all users in the database&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;POST&lt;/strong&gt; '/users': Creates a new user in the database if it's valid&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GET&lt;/strong&gt; '/users/:id': Get's a user by their ID&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DELETE&lt;/strong&gt; '/users/:id': Delete's a user by their ID&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Setting up the database
&lt;/h3&gt;

&lt;p&gt;We'll also want a database for this, so we'll pull in the trusty &lt;a href="https://github.com/raku-community-modules/DBIish" rel="noopener noreferrer"&gt;DBIish&lt;/a&gt; module maintained by the Raku Community.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;zef &lt;span class="nb"&gt;install &lt;/span&gt;DBIish
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We're going to be using SQLite3 for this so make sure you have the necessary libs installed on your machine. On an Ubuntu box that would look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;sqlite3 libsqlite3-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's hook up &lt;code&gt;DBIish&lt;/code&gt; into our existing code. We'll simply always run the create script for our table whenever the server starts, just to keep it fairly simple.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use DBIish;

my $db = DBIish.connect('SQLite', :database&amp;lt;user-db.sqlite3&amp;gt;);

$db.execute(q:to/SQL/);
CREATE TABLE IF NOT EXISTS user (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name VARCHAR(20),
    age INTEGER,
    email VARCHAR
)
SQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code is fairly straight forward, but I'll break it down a little bit for people who haven't use &lt;code&gt;DBIish&lt;/code&gt; before.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use DBIish;

my $db = DBIish.connect('SQLite', :database&amp;lt;user-db.sqlite3&amp;gt;);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, we import &lt;code&gt;DBIish&lt;/code&gt; then we assign a new variable &lt;code&gt;$db&lt;/code&gt; to hold our connection, which is a SQLite3 connection, with filename &lt;code&gt;user-db.sqlite3&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$db.execute(q:to/SQL/);
CREATE TABLE IF NOT EXISTS user (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name VARCHAR(20),
    age INTEGER,
    email VARCHAR
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we try to create our table, note this will run every time we run this script. The whole &lt;code&gt;q:to/SQL/&lt;/code&gt; thing basically says: Read the following lines as a string until you read the end-sequence specified in between the /'s.&lt;/p&gt;

&lt;p&gt;Overall our entire file 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;use Humming-Bird::Core;
use DBIish;

my $db = DBIish.connect('SQLite', :database&amp;lt;user-db.sqlite3&amp;gt;);

$db.execute(q:to/SQL/);
CREATE TABLE IF NOT EXISTS user (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name VARCHAR(20),
    age INTEGER,
    email VARCHAR
)
SQL

get('/', -&amp;gt; $request, $response {
    $response.html('&amp;lt;h1&amp;gt;Hello World!&amp;lt;/h1&amp;gt;')
});

listen(8080);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Setting up our end points
&lt;/h3&gt;

&lt;p&gt;Now that our database is good to go, lets begin working on our endpoints, first up let's make an endpoint for getting all of the users.&lt;/p&gt;

&lt;p&gt;We can express this simply as just returning the "jsonified" contents of our database. Humming-Bird depends on a module called &lt;code&gt;JSON::Fast&lt;/code&gt;, we should import that too. Add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use JSON::Fast;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to the top of our project to pull it in. It gives us access to the &lt;code&gt;to-json&lt;/code&gt; and &lt;code&gt;from-json&lt;/code&gt; sub-routines.&lt;/p&gt;

&lt;h4&gt;
  
  
  Getting all users
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get('/users', -&amp;gt; $request, $response {
    my @user-rows = $db.execute('SELECT * FROM user').allrows(:array-of-hash);
    my $json = to-json(@user-rows);
    $response.json($json);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will, select all of the users from the database as an array of hashes, then convert it to JSON with &lt;code&gt;JSON::Fast&lt;/code&gt;'s &lt;code&gt;to-json&lt;/code&gt;, then send it with content-type JSON via &lt;code&gt;$response.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Humming-Bird doesn't really do any magic, the &lt;code&gt;.json&lt;/code&gt; and &lt;code&gt;.html&lt;/code&gt; methods are just wrappers for: &lt;code&gt;.write($body, 'application/json')&lt;/code&gt; and &lt;code&gt;.write($body, 'text/html')&lt;/code&gt; respectively. Write just writes a &lt;code&gt;Buf&lt;/code&gt; or &lt;code&gt;Str&lt;/code&gt; to the body of the response.&lt;/p&gt;

&lt;h4&gt;
  
  
  Creating a user
&lt;/h4&gt;

&lt;p&gt;Now let's create a user with a &lt;code&gt;POST&lt;/code&gt; request. This is really simple using &lt;code&gt;$request.content&lt;/code&gt;, which will convert the JSON of the request to a Raku &lt;code&gt;Hash&lt;/code&gt; for you.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sub validate-user(%user) {
    # I'll leave this up to you :^)
    %user&amp;lt;age&amp;gt; &amp;gt; 18;
}

post('/users', -&amp;gt; $request, $response {
    my %user = $request.content;
    if validate-user(%user) {
        $db.execute('INSERT INTO user (name, age, email) VALUES (?, ?, ?)', %user&amp;lt;name&amp;gt;, %user&amp;lt;age&amp;gt;, %user&amp;lt;email&amp;gt;);
        $response.status(201).json(to-json(%user));
    } else {
        $response.status(400).write('Bad Request :(');
    }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'm letting you implement your own validation, so for now we just assume the user is valid unless their age is less than 18. Then we register our &lt;code&gt;POST&lt;/code&gt; route, then we get the &lt;code&gt;.content&lt;/code&gt; (which is a hash converted from the JSON body), then we validate, then if it's valid send a response with status &lt;code&gt;201 Created&lt;/code&gt; and write back the JSON that was sent to us. Otherwise send a bad-request response.&lt;/p&gt;

&lt;p&gt;We can test this endpoint with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{ "name": "bob", "age": 32, "email": "bob@gmail.com" }'&lt;/span&gt; http://localhost:8080/users
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if we change the age to say 14, you should see a &lt;code&gt;400 Bad Request&lt;/code&gt; response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{ "name": "bob", "age": 14, "email": "bob@gmail.com" }'&lt;/span&gt; http://localhost:8080/users
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally if we check our database by browsing to &lt;code&gt;http://localhost:8080/users&lt;/code&gt; we should see the user we created. In my case I ran the insert a few times.&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%2F5opaalg4evbnen6tqlpo.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%2F5opaalg4evbnen6tqlpo.png" alt="users get request results" width="435" height="743"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Getting an individual user
&lt;/h4&gt;

&lt;p&gt;This is a really simple end-point, the only difference between this and the getting all users is we have to get an ID from the request parameters.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get('/users/:id', -&amp;gt; $request, $response {
    my $id = $request.param('id');
    my @users = $db.execute('SELECT * FROM user WHERE id = ?', $id).allrows(:array-of-hash);

    return $response.status(404).html("User with id $id not found.") unless @users.elems == 1;

    $response.json(to-json(@users[0]));
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we get the &lt;code&gt;id&lt;/code&gt; from the requests parameters, specified in the route declaration, then we execute a DB query trying to find a user with that ID. If we don't get exactly one user back, we return a &lt;code&gt;404 Not Found&lt;/code&gt; status, otherwise we return a JSON response of the user we found.&lt;/p&gt;

&lt;p&gt;If you navigate to &lt;code&gt;http://localhost:8080/users/1&lt;/code&gt; you should see a user you inserted (if not you'll need to insert some!)&lt;/p&gt;

&lt;h4&gt;
  
  
  Deleting a user
&lt;/h4&gt;

&lt;p&gt;Another simple endpoint, this one will be very similar to the getting of a single user but instead we'll execute a DB delete then return nothing but a &lt;code&gt;204 No Content&lt;/code&gt; response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;delete('/users/:id', -&amp;gt; $request, $response {
    my $id = $request.param('id');

    try {
        CATCH { default { return $response.status(404).html("User with id $id not found.") } }
        $db.execute('DELETE FROM user WHERE id = ?', $id);
        $response.status(204);
    }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Major difference here is we use a try/catch block, you don't need to. Since Humming-Bird is functional I actually think it would be better practice to use a Monad type for handling errors something like &lt;a href="https://github.com/rawleyfowler/Monad-Result" rel="noopener noreferrer"&gt;Monad::Result&lt;/a&gt;,&lt;br&gt;
but that's the beautiful part of Humming-Bird, it accommodates everyone's preferences.&lt;/p&gt;
&lt;h2&gt;
  
  
  Middleware
&lt;/h2&gt;

&lt;p&gt;Well, your manager was so impressed that you finished this service in one-day that they decided to ask for a new feature! You should only be able to access the &lt;code&gt;DELETE&lt;/code&gt; and &lt;code&gt;POST&lt;/code&gt; routes if you have the magic passphrase of &lt;code&gt;foobar&lt;/code&gt; in the &lt;code&gt;X-AUTH&lt;/code&gt; header of your request.&lt;/p&gt;

&lt;p&gt;Humming-Bird supports rich middleware development, using you guessed it, functions. So let's quickly write up our final middleware requirement.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sub auth-middleware($request, $response, &amp;amp;next) {
    without $request.header('X-AUTH') {
        return $response.status(401).write('unauthorized')
    }

    my $request-header = $request.header('X-AUTH');

    if $request-header ne 'foobar' {
        return $response.status(401).write('unauthorized');
    }

    &amp;amp;next();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A middleware is described as a function that takes a request, and a response, and finally a pointer to the next function in the &lt;a href="https://github.com/rawleyfowler/Humming-Bird/blob/6dbbeb360ca63604689768c641130c7d4009bd3e/lib/Humming-Bird/Core.rakumod#L318" rel="noopener noreferrer"&gt;middleware chain&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To register this middleware with a route, all we have to do is add it to the tail of the route delcaration like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;delete('/users/:id', -&amp;gt; $request, $response {
    my $id = $request.param('id');

    try {
        CATCH { default { return $response.status(404).html("User with id $id not found.") } }
        $db.execute('DELETE FROM user WHERE id = ?', $id);
        $response.status(204);
    }
}, [ &amp;amp;auth-middleware ]); # Added auth middleware
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if you hit either endpoint without an &lt;code&gt;X-AUTH&lt;/code&gt;, or a non &lt;code&gt;foobar&lt;/code&gt; &lt;code&gt;X-AUTH&lt;/code&gt; header you will see a &lt;code&gt;401 Unauthorized&lt;/code&gt; screen. Otherwise, we'll slide on through to our end-points.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final code
&lt;/h2&gt;

&lt;p&gt;You can find the final code on &lt;a href="https://github.com/rawleyfowler/Humming-Bird-Microservice/blob/main/app.raku" rel="noopener noreferrer"&gt;github&lt;/a&gt;!&lt;/p&gt;

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

&lt;p&gt;Humming-Bird makes it really easy to spin up all sorts of web-applications leveraging Raku's vibrant and welcoming ecosystem. If you're interested in deploying a service like this to production make sure you check out the &lt;a href="https://github.com/rawleyfowler/Humming-Bird/tree/main/examples/docker" rel="noopener noreferrer"&gt;docker example&lt;/a&gt; on github. Just like any application layer framework, Humming-Bird is &lt;strong&gt;NOT&lt;/strong&gt; designed to face the internet directly, please reverse-proxy it with NGiNX or Apache2. If you have any questions, or find an issue with Humming-Bird please refer to the &lt;a href="https://github.com/rawleyfowler/Humming-Bird/issues" rel="noopener noreferrer"&gt;issue section&lt;/a&gt; on github.&lt;/p&gt;

&lt;p&gt;Thanks for reading, Raku rocks!&lt;/p&gt;

</description>
      <category>raku</category>
      <category>webdev</category>
      <category>microservices</category>
    </item>
  </channel>
</rss>
