Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much

Interpolating variables in JSON string

by reisinge (Friar)
on Jan 29, 2013 at 11:25 UTC ( #1015856=perlquestion: print w/replies, xml ) Need Help??
reisinge has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks,

I am authenticating through Rackspace API with the following code (using LWP):

sub authenticate { # Create a request my $req = HTTP::Request->new( POST => '' +); $req->content_type('application/json'); #my $json = '{"auth":{"RAX-KSKEY:apiKeyCredentials":{"username":"f +oo", "apiKey":"00000000000000000000000000000000"}}}'; my $json = quotemeta( {"auth":{"RAX-KSKEY:apiKeyCredentials":{"use +rname":$USERNAME, "apiKey":$API_KEY}}} ); $req->content( $json ); # Pass request to the user agent and get a response back my $res = $ua->request($req); # Check the outcome of the response if ( $res->is_success ) { # Do stuff ... } else { print $res->status_line, "\n"; } }

The problem is that I am not able to interpolate the variables in JSON string ($USERNAME and $API_KEY) - I am getting 400 BadRequest response. I have tried quotemeta (in the code snippet above), \Q and \E operators, escaping JSON double quotes with \.

The commented out $json line (with hard-coded credentials) works just fine.

We are what we repeatedly do. Excellence, then, is not an act but a habit. -- Will Durant (Aristotle)

Replies are listed 'Best First'.
Re: Interpolating variables in JSON string
by moritz (Cardinal) on Jan 29, 2013 at 11:34 UTC

    The proper way to create JSON strings is to first create a data structure in Perl that matches the desired output structure, and then run it through a JSON module like JSON or JSON::XS:

    use JSON qw/encode_json/; my $data = { auth => { "RAX-KSKEY:apiKeyCredentials" => { username => $USERNAME, apiKey => $API_KEY, }, }, }; my $json = encode_json($data);
Re: Interpolating variables in JSON string
by Corion (Pope) on Jan 29, 2013 at 11:28 UTC
Re: Interpolating variables in JSON string
by roboticus (Chancellor) on Jan 29, 2013 at 11:49 UTC


    I agree with the previous posters. However, it looks like you're just forgetting to put quotes around $USERNAME and $API_KEY. JSON is going to want quotes around string values, and you're just dropping them in without the quotes. You probably need:

    my $json = quotemeta( {"auth":{"RAX-KSKEY:apiKeyCredentials":{"usernam +e":"$USERNAME", "apiKey":"$API_KEY"}}} );

    So while this may get you going for now, just remember that it'll come back to bite you if you're not careful. Hence, the aforementioned suggestions.


    When your only tool is a hammer, all problems look like your thumb.

Re: Interpolating variables in JSON string
by muba (Priest) on Jan 29, 2013 at 13:52 UTC

    The line

    my $json = quotemeta( {"auth":{"RAX-KSKEY:apiKeyCredentials":{"use +rname":$USERNAME, "apiKey":$API_KEY}}} );
    makes no sense. The character : is only part of the Perl syntax in rather specific places, and this isn't one of them. I get a syntax error message for this line.

    The Perl equivalent of a JSON map is called a hash. Traditionally we use => to separate keys from their values, not :.

    my $json = quotemeta( {"auth" => {"RAX-KSKEY:apiKeyCredentials" => + {"username" => $USERNAME, "apiKey" => $API_KEY}}} );

    But even that would make little sense. That line would make the data structure, return a reference to it, try to quotemeta that reference, and store that in $json. So $json would end up being something like "HASH\(0x33c218\)". You don't need quotemeta here — you only need quotemeta when you're about to use a string inside a regular expressions and you're afraid that your string might have regex meta characters while you actually want to match them literally. What you do need is a real JSON module, like the good monks before me already suggested.

Re: Interpolating variables in JSON string
by Anonymous Monk on Jan 29, 2013 at 13:23 UTC
    It is definitely easier to use a JSON package, as noted, because this authentication request is only going to be the first of many requests that you will be sending to this host. Do as the Romans do ...

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1015856]
Front-paged by Arunbear
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2018-06-19 02:38 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (111 votes). Check out past polls.