How to make HTTP requests in Raku (Perl 6)

It took me a little while to figure out how to make web requests in Raku, because there weren’t any immediate answers in the search results. Here are some notes in case anyone else is searching.

I’m just getting started with Raku and there might be better ways, but this was enough to at least get my script working. If anyone has tips, leave a comment below.

Edit: I started with Cro::HTTP::Client but then found out about HTTP::Tiny and HTTP::UserAgent. I’ve updated this post with links to all three.

HTTP::Tiny

Install HTTP::Tiny and HTTP::UserAgent:

$ zef install HTTP::Tiny
$ zef install HTTP::UserAgent

(If you don’t already have zef or Raku, you can get them with rakubrew.)

If you’re going to work with JSON, also install this:

$ zef install JSON::Tiny

Related: How to use JSON in Raku

Here’s a script that fetches the latest topics from this forum as JSON and prints the titles of the latest topics:

use HTTP::Tiny;
use JSON::Tiny;

my $url = 'https://forum.codeselfstudy.com/latest.json';
my $resp = HTTP::Tiny.new.get: $url;

# If you want information about the response:
# say "$resp<headers>";
# say $resp<status>;
# say $resp<reason>

# `$json` contains the raw JSON string
my $json = $resp<content>.decode;

# `%data` is a Raku hash
my %data = from-json($json);

for %data<topic_list><topics>[] -> $topic {
    say $topic<fancy_title>;
}

If you seen an error that says something like

HTTPS requests not supported: IO::Socket::SSL:ver<0.0.2+> must be installed

be sure that you installed the regular HTTP::UserAgent in addition to HTTP::Tiny.

See the docs for more information.

HTTP::UserAgent

Here’s a version of the above code that uses HTTP::UserAgent instead of HTTP::Tiny:

use HTTP::UserAgent;
use JSON::Tiny;

my $client = HTTP::UserAgent.new;
$client.timeout = 10;

my $url = 'https://forum.codeselfstudy.com/latest.json';
my $resp = $client.get($url);

my %data = from-json($resp.content);

my @topics = %data<topic_list><topics>[];

for @topics -> $topic {
    say $topic<fancy_title>;
}

More information:

Cro::HTTP::Client

This was the first solution that I found, but the other two listed above might be better if you’re just making simple HTTP requests and don’t need everything else that Cro has.

To do it this way, first install Cro:

$ zef install --/test cro

Then write a script, script.raku:

use Cro::HTTP::Client;

my $client = Cro::HTTP::Client.new(
    # headers can be added here
    headers => [
        User-Agent => 'Cro',
        referer => 'http://example.com/',
    ]
);

# a URL with the current position of the ISS in JSON
my $url = 'http://api.open-notify.org/iss-now.json';

my $resp = await $client.get($url);
my $body = await $resp.body;

# print the $body
say $body;

# `$body` is a hash, so you can print a field in the usual way
say $body<iss_position>;

Then run the program with:

$ raku script.raku

The documentation page is here:

WWW

There’s also a library called WWW that looks interesting, but I had trouble installing it with zef. (There is an open issue in the repo.) It might be worth checking out at some point.