networking intermediate

How to create a REST API client in Perl?

Question

How to create a REST API client in Perl?

Creating a REST API client in Perl typically requires sending HTTP requests and parsing JSON responses. The common approach uses LWP::UserAgent for HTTP and a JSON module like JSON::MaybeXS for encoding/decoding. However, in sandbox environments (especially those lacking SSL certificates), HTTPS requests may fail due to SSL verification errors.

The key to running a REST client example safely in a sandbox is to avoid actual network access by simulating responses or focusing on local data. Since the sandbox here blocks network and file access, attempting a real HTTPS request will time out or fail.

To provide a runnable, sandbox-safe example demonstrating REST client usage, we can:

  • Create HTTP request and response objects programmatically without sending.
  • Show how to encode and decode JSON data locally.
  • Explain how LWP::UserAgent and HTTP::Request work, without making external calls.

Perl Concepts Highlighted

  • Sigils: Scalars $, arrays @, array refs @{}, hashes %.
  • Context sensitivity: scalar(@array) returns array length.
  • TMTOWTDI: Other HTTP modules exist (HTTP::Tiny, Mojo::UserAgent), but LWP::UserAgent is classic.

Common Pitfalls Avoided

  • Network calls blocked in sandbox environment.
  • SSL verification errors due to missing CA certificates.
  • Incorrect header formats.

Sandbox-friendly example: building a REST API client structure without network

#!/usr/bin/perl
use strict;
use warnings;
use LWP::UserAgent;
use JSON::MaybeXS;
use HTTP::Request;

# Create JSON data representing a typical API response
my $json_response = q|
[
  { "id": 1, "title": "First Post", "body": "Hello World" },
  { "id": 2, "title": "Second Post", "body": "More content" }
]
|;

# Decode JSON data to Perl arrayref
my $posts = decode_json($json_response);

print "Simulated fetch: ", scalar(@$posts), " posts.\n";
print "First post title: $posts->[0]{title}\n";

# Prepare data to POST (simulate creating a new post)
my $new_post_data = {
  title => "foo",
  body  => "bar",
  userId => 1,
};

my $json_body = encode_json($new_post_data);

# Create a HTTP POST request object with headers
my @headers = (
  'Accept'       => 'application/json',
  'Content-Type' => 'application/json',
);

my $url = 'https://example.com/api/posts';

my $post_request = HTTP::Request->new('POST', $url, [@headers], $json_body);

print "\nPrepared POST request:\n";
print $post_request->method, " ", $post_request->uri, "\n";
print "Headers:\n";
for my $header ($post_request->headers->header_field_names) {
    print "  $header: ", $post_request->header($header), "\n";
}
print "Content:\n", $post_request->content, "\n";

# Normally, you would send request with $ua->request($post_request),
# but network is not permitted here.

print "\nNote: Network requests disabled in this sandbox example.\n";

How this example works:

  • Simulates JSON fetching by decoding a hardcoded JSON string locally.
  • Shows how to parse JSON to Perl data structures via decode_json.
  • Creates and prints a HTTP::Request object for a POST, including headers and JSON body.
  • Prints request details instead of performing network calls (which are not allowed).

Notes

  • This example runs safely in any sandbox since it does not rely on outbound network or files.
  • Under normal conditions, you would send requests with LWP::UserAgent's get or request methods.
  • Disabling SSL verification (ssl_opts) is often needed for sandbox tests—but avoid it in production.

This approach balances demonstrating REST client code structure with sandbox constraints, illustrating Perl-specific features like data structures, HTTP requests, sigils, and JSON handling without external dependencies.

Verified Code

Executed in a sandbox to capture real output. • v5.34.1 • 47ms

Tip: edit code and use “Run (Browser)”. Server runs always execute the published, verified snippet.
STDOUT
Simulated fetch: 2 posts.
First post title: First Post

Prepared POST request:
POST https://example.com/api/posts
Headers:
  Accept: application/json
  Content-Type: application/json
Content:
{"title":"foo","userId":1,"body":"bar"}

Note: Network requests disabled in this sandbox example.
STDERR
(empty)

Was this helpful?

Related Questions