Web Development with Cro

46.1 A Cro HTTP Service

# service.raku   (zef install --/test cro)
use Cro::HTTP::Router;
use Cro::HTTP::Server;

my %todos;
my $next-id = 1;

my $application = route {
    get -> {
        content 'text/plain', 'Todo API';
    }
    get -> 'todos' {
        content 'application/json', %todos.values.sort(*<id>).Array;
    }
    get -> 'todos', Int $id {
        with %todos{$id} { content 'application/json', $_ }
        else { not-found }
    }
    post -> 'todos' {
        request-body -> %json {
            if %json<title> -> $title {
                my %todo = id => $next-id, title => $title, done => False;
                %todos{$next-id++} = %todo;
                created "/todos/%todo<id>", 'application/json', %todo;
            }
            else { bad-request 'text/plain', 'title is required' }
        }
    }
    delete -> 'todos', Int $id {
        %todos{$id}:delete ?? content('text/plain', 'deleted') !! not-found;
    }
    get -> 'greet', $name, :$greeting = 'Hello' {          # query parameter ?greeting=...
        content 'text/plain', "$greeting, $name!";
    }
}

my Cro::Service $service = Cro::HTTP::Server.new(
    host => '0.0.0.0', port => 10000, :$application,
);
$service.start;
say "
…
raku service.raku
curl -X POST -H 'Content-Type: application/json' -d '{"title":"Learn Cro"}' localhost:10000/todos
cro stub http todo-service todo-service   # scaffold with the cro CLI
cro run                                   # dev server with auto-restart

46.2 More Cro Features

Middleware (before, after, around), sessions and authentication (Cro::HTTP::Session::InMemory, JWT via Cro::HTTP::Auth), WebSockets (web-socket -> $incoming { supply { whenever $incoming -> $msg { emit "echo: {await $msg.body-text}" } } }), static files (static 'public', @path), templates (Cro::WebApp::Template), the HTTP client (Cro::HTTP::Client), HTTP/2, TLS, and Cro::ZeroMQ.

use Cro::HTTP::Client;
my $resp = await Cro::HTTP::Client.get('https://api.github.com/repos/rakudo/rakudo',
    headers => [User-Agent => 'raku-course']);
my %repo = await $resp.body;
say "Stars: %repo<stargazers_count>";