NetSDS...:JSRPC(3pm)

πŸ“¦
version 1.301 Β· 2 versions
, in debian bookworm, debian trixie, ubuntu jammy, ubuntu noble, ubuntu resolute

πŸ’– NetSDS::App::JSRPC β€” the manual page, but make it cute πŸ’–

okay bestie, pull up a chair, because this is the NetSDS::App::JSRPC page from section 3pm (Perl user-contributed docs, iykyk) and it's genuinely iconic. it's a JSON-RPC server framework and we're gonna go through the whole thing together, no skips, no skimming. ✨


🌸 NAME 🌸

NetSDS::App::JSRPC β€” literally a JSON-RPC server framework. that's the whole vibe. that's the assignment. 🫢


πŸ¦‹ SYNOPSIS πŸ¦‹

here's the moment you've been waiting for, the whole server in one glance:

#!/usr/bin/env perl
# JSON-RPC server

use 5.8.0;
use warnings;
use strict;

JServer->run();

1;

# Server application logic

package JServer;

use base 'NetSDS::App::JSRPC';

# This method is available via JSON-RPC
sub sum {
    my ($self, $param) = @_;
    return $$param[0] + $$param[1];
}

1;

see how the sum sub is just sitting there being available over JSON-RPC? main character energy fr fr. πŸ‘‘


πŸ’… DESCRIPTION πŸ’…

so NetSDS::App::JSRPC is the module that implements a framework for a common JSON-RPC based server application. and what is JSON-RPC, you ask? it's a HTTP based protocol that gives you remote procedure call (RPC) functionality, using JSON to encapsulate the requests and the responses. it's giving "call a function on a whole other machine, but make it JSON". 🌈

this implementation is built on top of the NetSDS::App::FCGI module, and it expects to be run as a FastCGI or CGI application. periodt.

the class inheritance diagram goes like this, look at the little tree, it's so tidy:

          [NetSDS::App::JSRPC] - JSON-RPC server
                   |
          [NetSDS::App::FCGI] - CGI/FCGI application
                   |
             [NetSDS::App] - common application
                   |
        [NetSDS::Class::Abstract] - abstract class

and both the request AND the response are JSON-encoded strings, riding through the HTTP protocol as data of the 'application/json' MIME type. no cap. πŸ’–


πŸŽ€ APPLICATION DEVELOPMENT πŸŽ€

okay so you wanna build your own JSON-RPC server app? step one, bestie: create an application class that inherits from NetSDS::App::JSRPC.

here's an empty little baby application, adorable, does nothing, slays anyway:

#!/usr/bin/env perl

JSApp->run(
    conf_file => '/etc/NetSDS/jsonapp.conf'
);

package JSApp;

use base 'NetSDS::App::JSRPC';

1;

and then, lowkey, you're probably gonna want some specific code for your application startup:

sub start {
    my ($self) = @_;

    connect_to_dbms();
    query_for_external_startup_config();
    do_other_initialization();

}

and of course, of COURSE, you gotta add the methods that actually provide the functions. otherwise what are we even doing here:

sub send_sms {
    my ($self, $params) = @_;

    return $self->{kannel}->send(
        from => $params{'from'},
        to => $params{'to'},
        text => $params{'text'},
    );
}

sub kill_smsc {
    my ($self, $params) = @_;

    # 1M of MT SM should be enough to kill SMSC!
    # Otherwise we call it unbreakable :-)

    for (my $i=1; $<100000000; $i++) {
        $self->{kannel}->send(
            %mt_sm_parameters,
        );
    }

    if (smsc_still_alive()) {
        return $self->error("Can't kill SMSC! Need more power!");
    }
}

that comment in kill_smsc? "1M of MT SM should be enough to kill SMSC! Otherwise we call it unbreakable :-)" β€” iconic, unhinged, obsessed. 😭


✨ ADVANCED FUNCTIONALITY ✨

NetSDS::App::JSRPC gives you two methods that you can use to implement logic that's more complex than your average RPC straight to one class. let's get into it.

🌟 can_method() β€” method availability checking

by default this is literally just a wrapper around the UNIVERSAL::can function. but (and this is the fun part) you can rewrite it to check for methods in other classes, or even to construct the necessary methods on the fly. wild. πŸ¦‹

🌟 process_call() β€” method dispatching

by default it just calls the local class method with the same name as the one in the JSON-RPC call. and of course, obviously, it can be overwritten so you can process the query some other way. your server, your rules. πŸ’…

this code describes the logic of call processing:

# It's not real code

if (can_method($json_method)) {
    process_call($json_method, $json_params);
}

for more details, read the documentation below. it's right there, we're going. πŸŽ€


πŸ‘‘ CLASS API πŸ‘‘

new(%params) β€” class constructor

it's an internally used constructor, and it shouldn't be used from the application directly. hands off, bestie, it's for the framework. πŸ™ˆ

process() β€” main JSON-RPC iteration

this is an internal method that implements the JSON-RPC call processing. that's the whole thing.

can_method($method_name) β€” check method availability

this method lets you check if some method is available for execution. by default it uses UNIVERSAL::can, but it may be rewritten to implement a more complex calls dispatcher. glow-up potential: high.

  • Parameters: method name (string)
  • Returns: true if method execution is allowed, false otherwise.

example:

# Rewrite can_method() to search in other class
sub can_method {
    my ($self, $method) = @_;
    return Other::Class->can($method);
}

process_call($method, $params) β€” execute method call

  • Parameters: method name, parameters.
  • Returns: parameters from the executed method, as is. no touchy, no transformy.

example:

# Rewrite process_call() to use other class
sub process_call {
    my ( $self, $method, $params ) = @_;
    return Other::Class->$method($params);
}

_request_parse($post_data) β€” parse HTTP POST

  • Parameters: HTTP POST data as a string
  • Returns: request method, parameters, id

_make_result(%params) β€” prepare positive response

this is an internal method for encoding a JSON-RPC response string.

  • Parameters:
    • id β€” the same as request Id (see specification)
    • result β€” method result
  • Returns: JSON encoded response message.

_make_error(%params) β€” prepare error response

internal method implementing the JSON-RPC error response.

  • Parameters:
    • id β€” the same as request Id (see specification)
    • code β€” error code (default is -32603, internal error)
    • message β€” error message
  • Returns: JSON encoded error message

πŸ“ EXAMPLES πŸ“

go look at the samples/app_jsrpc.fcgi application. it's right there waiting for you. 🫢


🌈 SEE ALSO 🌈


πŸ’œ TODO πŸ’œ

  1. Move error codes to constants to provide more clear code.
  2. Implement objects/classes support.

(future us is gonna eat with these, fr fr.)


🌸 AUTHOR 🌸

Michael Bochkaryov <misha@rattler.kiev.ua>


πŸŽ€ LICENSE πŸŽ€

Copyright (C) 2008-2009 Net Style Ltd.

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA


and that's the whole page, bestie. this one shipped as perl v5.32.1 on 2021-12-26, and honestly? it ate. go build something with it. πŸ’–βœ¨πŸ¦‹