How to send JSON data in POST request with LWP::UserAgent?
Question
How to send JSON data in POST request with LWP::UserAgent?
Sending JSON Data in a POST Request with LWP::UserAgent
When working with HTTP APIs in Perl, LWP::UserAgent is one of the go-to modules for making web requests. Sending JSON data in a POST request is a common task, typically required when interacting with RESTful APIs. This involves two key steps:
- Encoding your data structure into JSON format.
- Setting the proper
Content-Typeheader toapplication/json.
Perl’s JSON module makes encoding data to JSON straightforward. We then set the POST content to the JSON string and specify the correct content type, so the server knows how to interpret the payload.
Key Concepts
- Sigils: Scalars (
$) hold JSON strings; references (e.g., hashes or arrays) are encoded. - Context: JSON encoding expects normal Perl data structures (hashrefs, arrayrefs).
- TMTOWTDI: There are multiple JSON modules (like
JSON::XS,JSON::PP), but the coreJSONmodule is often sufficient.
Note: LWP::UserAgent->post() can take parameters either as a form or as raw content. For JSON, you must use the raw content approach.
Example: Sending JSON POST with LWP::UserAgent
#!/usr/bin/perl
use strict;
use warnings;
use LWP::UserAgent;
use JSON;
# Create a user agent object
my $ua = LWP::UserAgent->new;
# Define a Perl data structure to encode as JSON
my $data = {
name => "Alice",
age => 30,
interests => ['Perl', 'Web APIs', 'JSON']
};
# Encode data structure to JSON string
my $json = encode_json($data);
# Set the target URL (example placeholder)
my $url = 'http://httpbin.org/post';
# Make the POST request with JSON content and proper header
my $response = $ua->post(
$url,
'Content-Type' => 'application/json',
Content => $json,
);
# Check the response and print content or error
if ($response->is_success) {
print "Response received:\n";
print $response->decoded_content;
} else {
warn "HTTP POST failed: ", $response->status_line, "\n";
}
Explanation
encode_json($data)converts the Perl hashref into a JSON string.- The
Content-Typeheader explicitly tells the server the payload is JSON. Content => $jsonsends the raw JSON string as the POST body.http://httpbin.org/postis a great testing endpoint that echoes back your POST data.
Common Gotchas
- Using the
POST $url, \%formform submits content asapplication/x-www-form-urlencoded, not JSON. - For older Perl versions, ensure
JSONmodule is installed (core from Perl 5.14+). - Remember to handle UTF-8 encoding if your data contains Unicode characters;
encode_jsontakes care of UTF-8 encoding internally. - Always check
$response->is_successbefore trusting the response content.
This approach works for Perl 5.10 and later with the standard core modules. For advanced use cases, modules like HTTP::Tiny or Mojo::UserAgent also support JSON POSTs but LWP::UserAgent remains widely used for backward compatibility.
Verified Code
Executed in a sandbox to capture real output. • v5.34.1 • 1735ms
Response received:
{
"args": {},
"data": "{\"interests\":[\"Perl\",\"Web APIs\",\"JSON\"],\"age\":30,\"name\":\"Alice\"}",
"files": {},
"form": {},
"headers": {
"Content-Length": "64",
"Content-Type": "application/json",
"Host": "httpbin.org",
"User-Agent": "libwww-perl/6.44",
"X-Amzn-Trace-Id": "Root=1-69534e87-0363109327ef8dc46f9a49eb"
},
"json": {
"age": 30,
"interests": [
"Perl",
"Web APIs",
"JSON"
],
"name": "Alice"
},
"origin": "107.167.18.100",
"url": "http://httpbin.org/post"
}
(empty)Was this helpful?
Related Questions
- How to handle gzip compressed responses with LWP in Perl?
- How to use LWP::Simple for quick GET requests in Perl?
- How to parse HTML response with HTML::TreeBuilder in Perl?
- How to use Mojo::UserAgent for HTTP requests in Perl?
- How to set connection keep-alive with LWP::UserAgent in Perl?
- How to use LWP::Protocol::https for HTTPS requests in Perl?