Giter Site home page Giter Site logo

respite's Introduction

NAME

Respite::Base - base class for Respite related modules that can be used from a server or commandline

SYNOPSIS

package Foo;
use base qw(Respite::Base);
my $meta = {lib_dirs => 1, dispatch_type => 'cache'};
sub api_meta { $meta }

package Foo::Bar;
sub somecall__meta { {desc => 'A method'} }
sub somecall {
    my ($self, $args) = @_;
    return {foo => 1};
}

my $f = Foo->new;
my $data = $f->bar_somecall;


#-----------------#

package Foo;

use strict;
use warnings;
use base qw(Respite::Base);

# sub api_meta { {} }  # optional configuration
sub api_meta {
    return shift->{'api_meta'} ||= { # vtable cached here
        methods => {
            foo => 'bar', # alias a method
            baz => sub { }, # custom
        },
        namespaces => {
            foo_child => 1,
            bar_child => 1,
        },
        lib_dirs => {
            $dir => 1, # load all .pm files as namespaces
        },
    };
}

sub foo__meta { {} }
sub foo {
    my ($self, $args) = @_;
    $self->validate_args($args);

    return {...};
}

my $obj = Foo->new;
$obj->run_method("foo", $args);
# will do logging and utf8 munging - used by Respite::Server or Respite::CommandLine

$obj->foo($args); # no logging or utf8 munging


###----------------------------------------------------------------###

use Respite::Base;
my $obj = Respite::Base->new({
    api_meta => {
        methods => {
            foo => 'bar',
        },
        namespaces => {
            Foo => {},
        },
    },
});

Respite_META

The module can specify a api_meta override, or a api_meta hashref can be passed to Respite::Base->new. The following keys are honored from api_meta.

  • methods

    Can be a hard coded list of supported methods.

      methods => {
          foo => 'bar',
          fii => sub { return {data => 'some data'} },
      },
    
  • namespaces

    Hard coded list of method namespaces that will be used to map methods to packages spaces.

      namespaces => {
          customer    => '__',
          package     => '__',
      },
    

    A module name will be generated from the namespace. The the methods reside in a different location, it is possible to pass along the package.

      namespaces => {
          customer => {
              match => '__',
              package => 'SomeSpace::Customer',
          },
      },
    

    Methods are looked for in this namespace package space. Method names used in the api must either begin with a __ (__foo_method), and/or they must have a corresponding __meta entry (foo_method__meta). This allows for non-Respite methods to remain non-Respite easily. Additionally you can use the restrict method call to narrow this down even farther.

  • lib_dirs

    Dynamic directory of method namespaces. Items in lib_dirs will be used for a path search that will populate a namespace entry.

      lib_dirs => {
          "$config::config{'rootdir_server'}/api_lib" => 1,
      },
    

    Depending upon the path chosen, it may be necessary to supply a pkg_prefix.

      lib_dirs => {
          "$config::config{'rootdir_server'}/lib/YAR" => {
               pkg_prefix => 'YAR',
          },
      },
    

    Alternately, it is possible to set lib_dirs equal to "1" which will make it automatically follow the previous behavior. Note though that additional looked up modules must be found relative to the location of the parent module (@INC is not used).

  • utf8_encoded

    Default false. When false, data passed should be properly utf8 decoded (or have no utf8 data at all). When true, data passed is assumed to be utf8 encoded meaning that it will need to be decoded before calling json->encode.

    Additionally, the true value can be a hashref of methods that need this treatment. This is useful if you know some of your methods have utf8 data, while others do not.

    (Note: Conversely when the non-json transport is finalized, it will need to call decode_utf8 to make sure data is ready for the transport.)

  • dispatch_type

    Can be one of new, cache, or morph. Default is new. When "new" is selected, a new object will be created with each dispatch call and it will contain a reference to the parent in the key named "base". When "cache" is selected, a cached object will be used - the object is cached inside of the base object. When "morph is selected, rather than creating a new object, the base object is temporarily blessed into the new object class.

  • enforce_requires_admin

    Default false. If true, then validate_args will honor the requires_admin by calling require_admin if it appears in the __meta for the method.

  • allow_nested

    Allow for nested package inheritance. The nested namespace package must provide its own api_meta.

METHOD NAME RESOLUTION

TODO - document how we go from an Respite method name to its corresponding location.

Talk about builtins, methods overrides, namespaces, lib_dirs, and the __ prefix and __meta suffix.

METHODS

This is an outdated list from the _Respite.pm import.

  • base

    When dispatch_type is set to new or cache, this method will provide access to the parent dispatching to the sub namespace.

  • base_class

    If a child namespace is used directly, base_class will be looked at when the base method is called to create a parent base object.

  • validate_args

    See Respite::Validate

  • verify_admin

    Uses Respite::Client to call the emp_auth service and verify a passed in token.

  • api_preload

    Called from Respite::Server when a server is being started. This method can be used to pre load all necessary modules to avoid a penalty later on. Note that any overrides should likely call ->SUPER::api_preload as well.

The following methods are normally set when called from Respite::Server or Respite::CommandLine. If Respite::Base is used outside of these mediums, then the corresponding $self->{'propertyname'} values must be set during initialization in order to use these methods. If namespaces are used, the child class will typically fail back and look at the ->base->method value if necessary.

  • remote_ip

    The IP on the client machine calling this service. This is advisory. Respite::Client will use cmdline for this value when called through Respite::CommandLine on the remote box.

  • remote_user

    The user on the client machine calling this service. This is advisory.

  • transport

    Defaults to ''. From Respite::Server it defaults to json (Respite), form (Post variables), and form-doc (autodoc interface). From Respite::CommandLine it defaults to cmdline. It is normal in web interfaces that this value should be set to gui.

  • api_ip

    The IP used to talk to the service when used as an Respite server. It will be cmdline when called from Respite::CommandLine.

  • api_brand

    The brand used during api communication. As a special case, if is_local is true, the $ENV{'PROV'} value can be used to specify the brand.

  • admin_user

    The authenticated administrative username. Will only be set if require_admin has been called. Dies is not set.

  • is_server

    Set by Respite::CommandLine and Respite::Server.

  • is_local

    Only true if transport is cmdline or gui. Essentially this is a "non-api" check.

  • is_authed

    True if admin_user is set. False if not (does not die).

  • employee

    Will return an Employee object based on admin_user.

RESPONSE

Responses from called methods should typically be hashrefs of data. These responses will be encoded by the appropriate system. Typically the encoding will be json (during Respite::Server), but possibly other forms (Perl, JSON, YAML, CSV) such as during Respite::CommandLine.

Methods can also return psgi style responses though this is typically more rare. (It allows for other encodings or page displays).

When a hashref is returned the following keys may also be returned to give additional information to the transport layer:

  • _utf8_encoded

    This flag signals that the data is already utf8 encoded meaning that if a JSON transport layer is used, the data will need to be first decoded before being passed to JSON->encode to avoid double encoding. Typically, this should be done by setting utf8_encoded in api_meta - though the _utf8_encoded flag allows for one-off operations.

  • _extra_headers

    This should be an arrayref of arrayrefs containing key/val pairs. When used under Respite::Server, these will be sent as additional http headers. When using Respite::Client, the headers can be seen in the 'headers' property of a response object (non-flat).

      sub __some_method {
          return {
              _extra_headers => [
                  ['Set-Cookie' => 'foo=bar'],
                  ['X-Some-Header' => 'someval'],
              ],
              normal_data_key => 'val',
          };
      }
    

respite's People

Contributors

fozzmoo avatar jayceh avatar jgoodman avatar mattmonsen avatar oaxlin avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar

respite's Issues

POSIX::tmpnam is unimplemented

Newer perl versions (e.g.5.28.x) don't implement POSIX::tmpnam anymore:


Unimplemented: POSIX::tmpnam(): use File::Temp instead at /opt/perl-5.28.1/lib/5.28.1/x86_64-linux/POSIX.pm line 185.

#   Failed test 'require Respite::Server::Test;'
#   at t/00-load.t line 12.
#     Tried to require 'Respite::Server::Test'.
#     Error:  Unimplemented: POSIX::tmpnam() at /home/cpansand/.cpan/build/2018120422/Respite-0.2-0/blib/lib/Respite/Server/Test.pm line 6.
# BEGIN failed--compilation aborted at /home/cpansand/.cpan/build/2018120422/Respite-0.2-0/blib/lib/Respite/Server/Test.pm line 6.
# Compilation failed in require at (eval 40) line 2.
# Looks like you failed 1 test of 7.
t/00-load.t ................... 
Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/7 subtests 
...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.