http://www.perlmonks.org?node_id=776135

Monks,

What is the current "preferred" way to do RPC calls to a different machine with Perl? Is SOAP still the main option?

A few years ago I was using a hand-rolled method of remote procedure calls. It involved Storable and some http requests. Oh, by the way, it sucked. Lots of AUTOLOAD and fiddling with @INC lead to code that was difficult to debug and maintain.

However, it did mean that code like the following would work whether the modules it used and the methods it called were "local" or "remote":

use My::Module; my $obj = My::Module->new( %args ); foreach my $item ( $obj->foo_items ) { $item->do_it; }# end foreach()

At the time we were using Class::DBI for a database ORM. A "stub" base-class on the "client" machines would handle the requests and responses, allowing us to use the same class names on the "client" machines as we did on the remote machine. This worked out very well, but because of the statelessness of http, we could not use database transactions. We used $Data::Dumper::Deparse semantics to serialize a coderef containing the transaction code, and then execute via eval($str) on the remote server. Again - this worked, but it was difficult to debug and maintain.

I wonder how this might work out a bit better at this time - with Moose now and with Perl6 arriving soon.

Replies are listed 'Best First'.
Re: Preferred RPC method?
by perrin (Chancellor) on Jun 30, 2009 at 23:02 UTC
    XML-RPC or JSON-RPC are probably your best bets. If your needs are simple enough, vanilla HTTP wuth query args may be enough (aka REST if you want to sound like you're doing something special).
Re: Preferred RPC method?
by ruoso (Curate) on Jul 01, 2009 at 13:38 UTC

    It's funny that you mention SOAP as the "main" option. Because SOAP was a PITA untill very recently, mostly because SOAP::Lite is really a mess. But today you have very interesting solutions to SOAP in Perl that are much more mature, much less messy and much more standards-compliant.

    On the other hand, SOAP is a protocol that expects a very strong and strict typing, that means you need to spec your data accordingly, which might be possible and even desired in a lot of cases, but on the other hand, writing a WSDL might be overkill for a lot of scenarios.

    That being said, if you choose SOAP, I'd first recommend you writing a XML Schema describing the data that you want to transfer, then writing a WSDL describing how you're going to transfer it, then you can use the following modules to implement it:

    • XML::Compile::SOAP
    • Catalyst::Controller::SOAP and Catalyst::Model::SOAP if you like frameworks

    But, as I said, that might be overkill for a lot of applications. SOAP is only worth the trouble when there's a need of data validation and consistency that can be documented as a XML Schema. Otherwise JSON is a great choice.

    daniel
Re: Preferred RPC method?
by ambrus (Abbot) on Jun 30, 2009 at 19:39 UTC

    It depends on what you want to do really. Sometimes it's better to use http or ssh.

      JSON-RPC might be an idea.

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: Preferred RPC method?
by Rhandom (Curate) on Jul 02, 2009 at 13:52 UTC
    I've done SOAP and many many custom XML interchanges. They are all either fairly cumbersome or they just feel heavy. Ninety-five percent of the time now I just use JSON. It is easy to add to any Catalyst, CGI::Appliation, CGI::Ex::App, or whatever type application.

    sub json_run_step { my $self = shift; my $form = $self->form; my $type = $form->{'type'}; my $data; my $ok = eval { die "Invalid type \"$type\"\n" if $type !~ /^[a-z]\w+$/; die "Invalid method \"$type\"\n" if ! $self->can($type); $data = $self->$type($form); }; if (! $ok) { $data = { error => "$@" || "An error occurred", }; } $self->cgix->print_content_type('application/x-javascript'); print JSON::to_json($data)."\n"; return 1; }

    With JSON, my exposed methods are easily available to other perl scripts, or more importantly, they are available to my javascript applications (AJAX isn't quite the word here as the "Asychronous" and "And XML" don't apply in many of my scripts - so all you are left with is the the J".

    I know that this sort of solution doesn't include parameter checking, but normally my methods include any of the bounds checking that I may need.

    my @a=qw(random brilliant braindead); print $a[rand(@a)];
Re: Preferred RPC method?
by sundialsvc4 (Abbot) on Jul 14, 2009 at 23:45 UTC

    I'll share the sentiment, “just use JSON.”

    SOAP, quite frankly, is massive overkill. Ditto WSDL. Why? Because, in the real world (imho...), things don't actually “change” much and thus you almost never have a need to “discover” anything about the server/service with which you desire to communicate. It's not a moving target:   it's a fixed target. (At least for your expected tenure with the company.) :-)

    In any case, if and when the interface between the two parties does change, it'll take much more than “a new WSDL” to actually make it work. Let's face it:   you're gonna have to change the code.

    In the real world, programs simply don't say, “gee, I'd like to do 'this'... so let me discover something that does 'this,' and then discover how to talk to it, and actually succeed in doing so.” Even though the WSDL specification et al are designed for more-or-less that scenario ... it just don't happen in real life, and so it is nothing more than a solution in search of a problem.

    Nearly all the time, “RPC” means “a web browser program, written in JavaScript, talking AJAX.” On the very rare occasions when it doesn't, the two machines in question are sure to be engaging in exactly the same conversation for many years to come. Ergo, the added complexity of XML RPC is simply wasted.

    I am a firm believer in shooting for “a complete and thorough solution to your problem,” but not for “a complete and thorough solution to more than your problem.” A committee dreamed up RPC XML. One guy dreamed up JSON. I think that means something really important ...