LedgerSMB Documentation

Description manuals and libraries
LedgerSMB Documentation > Perl Modules > LedgerSMB::Router
Source

NAME

LedgerSMB::Router - Module to dispatch web requests based on URL

DESCRIPTION

This module builds a map of URLs to application entry-points. In that sense, it does the same as Path::Map, Path::Router, Router::Simple, Router::R3 and many others.

This module takes the same approach as Path::Map (and possibly Router::R3) by building a tree of path segments and traversing the tree while matching the path. This approach contrasts with e.g. Path::Router and Router::Simple which build a list of all full paths, matching the URL to be matched to each route in the list until the first match.

Algorithm complexity of path dispatch depends on the number of segments in the path, for this module. For the modules which work off a list of routes, the algorithm complexity depends on the number of routes to be dispatched on.

Next to the router functionality, this module also provides a few DSL-like keywords to help define

SYNOPSIS

   # register a router and import dsl keywords
   use LedgerSMB::Router appname => 'erp';

   get '/route/to/endpoint' => sub {
     my ($env) = @_;

     # return a PSGI tripple
     return [ 200, [], [ 'body']];
   };

   post '/route/to/{parameterized}/{endpoint}' => sub {
     my ($env, %params) = @_;

     # return a PSGI tripple
     return [ 200, [], [ 'body' ]];
   }

MODULE METHODS

import

new (constructor)

METHODS

add_mapping( $route => $handler )

Adds a mapping from a route to a handler to the router. Routes are paths; routes consist of path segments which can be fixed, parameterized or - in case of the last segment - be the catch-all pseudo-segment; e.g.:

  /fixed/path/segments
  /parameterized/{path}/segments
  /route/to/catch/*

The above examples list, from top to bottom, a route with fixed segments, a route with a parameterized segment (:path, returned as the path parameter) and a route with a catch-all segment at the end.

The last route will match:

  /route/to/catch/fish
  /route/to/catch/fish/and/chips

The other two examples won't match more segments than the number in the route.

api_validator()

Returns a JSONSchema::Validator instance initialized from the accumulated schema fragment definitions declared in the various router definition modules.

lookup($path)

Matches $path against the registered routes, finding the most specific matching route. E.g. when matching /menu-nodes/new, both routes below match:

   /menu-nodes/new
   /menu-nodes/{id}

The first entry is the most specific one as :id is a generic match whereas new is a specific match.

In a list context, this function returns ($handler, \%values, \@wild, $route_path); in a scalar context, it returns a hash { handler = $handler, values => \%values, wild => \@wild, pathdef => $route_path }>.

dispatch($env)

Dispatches a request in a PSGI environment where routes have been registered through the DSL keywords listed below. The dispatch parameters (REQUEST_METHOD and PATH_INFO) are taken from $env.

Returns a PSGI 'response triplet', or, a 404 response when no matching route was found.

hooks($name [ => @hooks])

setting($name, [$value])

If $value is supplied, sets a configuration value to be used for all entry points created after the setting has been modified.

Returns the value of the setting (after modification, if applicable).

settings

Returns the settings as applied for new entry points.

DSL KEYWORDS

any \@request_types, $path => \&code =head2 del $path => \&code =head2 get $path => \&code =head2 head $path => \&code =head2 options $path => \&code =head2 patch $path => \&code =head2 post $path => \&code =head2 put $path => \&code

The code reference is a function of 3 parameters handler($env, $url_values, $wildcard_segments) where $env is the PSGI environment, $url_values is a hashref holding values of the URL parameters and $wildcard_segments is an arrayref with the URL segments matched by the terminating wildcard.

api path => \&code

Add web service API request/response validation wrapper around the code reference. Returns the path and a code reference which can be used as the argument list of the api entry point defining keywords:

  post api 'our/path/' => sub {
     my ($env, $req, $company, $body, $params, @rest) = @_;
     ...;
  };

The wrapper wants the api_schema setting to be assigned in order to be able to validate the validity of the request and the response.

In case third element of the PSGI triplet is undefined or the return value itself is undefined, a 404 Not Found response is generated.

The parameters to the coderef are:

$env

The PSGI environment hash.

$req

The PSGI Plack::Request::WithEncoding instance

$company

An authenticated LedgerSMB::Company instance

$body

The request body in case the request has media type 'application/json', which is cached here to prevent parsing the JSON body more than once.

$params

A hash containing the parameters parsed from the request path.

@rest

Any other parameters passed to the route entry point are forwarded here.

openapi_schema \*FH

Parses an OpenAPI (currently 3.0) definition from the fileref passed as the argument. The return value can be used to set the schema of the current file:

   set api_schema => openapi_schema( \*DATA );

error $req, $status_code, $headers, @errors =head2 hook $name => \&hook =head2 json =head2 locale $env =head2 set $setting => 'value' =head2 user $env

router $appname

Returns the router with routes registered for $appname as created by using this module;

  # create an 'erp' router
  use LedgerSMB::Router appname => 'erp';


  # create a 'LedgerSMB::MyPkg' router
  package LedgerSMB::MyPkg;
  use LedgerSMB::Router;

LICENSE AND COPYRIGHT

Copyright (C) 2020 The LedgerSMB Core Team

This file is licensed under the GNU General Public License version 2, or at your option any later version. A copy of the license should have been included with your software.