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.