Router Configuration

The request router is configured in the create_router_config() method of your application context.

from jivago.config.production_jivago_context import ProductionJivagoContext
from jivago.config.router.router_builder import RouterBuilder
from jivago.wsgi.routing.routing_rule import RoutingRule
from jivago.wsgi.routing.serving.static_file_routing_table import StaticFileRoutingTable


class MyApplicationContext(ProductionJivagoContext):

    def create_router_config(self) -> RouterBuilder:
        return super().create_router_config() \
            .add_rule(RoutingRule("/static", StaticFileRoutingTable("/var/www")))

Configuration itself is done by adding new rules to the router builder, using the add_rule method.

Routing rules

Each routing rule requires a prefix path which acts as a root path from which requests are served, and a RoutingTable which contains the actual route definitions. The rewrite_path parameter defaults to True and is used to remove the path prefix from the request object before invoking the resource class.

from jivago.wsgi.methods import GET
from jivago.wsgi.routing.routing_rule import RoutingRule
from jivago.wsgi.routing.serving.static_file_routing_table import StaticFileRoutingTable
from jivago.wsgi.routing.table.tree_routing_table import TreeRoutingTable

my_routing_table = TreeRoutingTable()
my_routing_table.register_route(GET, "/hello", HelloClass, HelloClass.get_hello)

root_rule = RoutingRule("/", my_routing_table)
my_rule = RoutingRule("/static", StaticFileRoutingTable("/var/www"), rewrite_path=True)
Example : Mapping all routes to the /api prefix

To completely override the default production or debug configuration, omit the super() call, and start with a fresh RouterBuilder.

from jivago.config.production_jivago_context import ProductionJivagoContext
from jivago.config.router.filtering.auto_discovering_filtering_rule import AutoDiscoveringFilteringRule
from jivago.config.router.filtering.filtering_rule import FilteringRule
from jivago.config.router.router_builder import RouterBuilder
from jivago.lang.annotations import Override
from jivago.wsgi.routing.routing_rule import RoutingRule
from jivago.wsgi.routing.table.auto_discovering_routing_table import AutoDiscoveringRoutingTable


class MyApplicationContext(ProductionJivagoContext):

    @Override
    def create_router_config(self) -> RouterBuilder:
        return RouterBuilder() \
            .add_rule(FilteringRule("*", self.get_default_filters())) \
            .add_rule(AutoDiscoveringFilteringRule("*", self.registry, self.root_package_name)) \
            .add_rule(RoutingRule("/api", AutoDiscoveringRoutingTable(self.registry, self.root_package_name)))
Note the required default rules for proper operation :
  • FilteringRule('*', self.get_default_filters())

    This rule adds all Jivago filters which are required for proper error and serialization handling.

  • AutoDiscoveringFilteringRule('*', self.registry, self.root_package_name)

    This rule registers user-defined request filters using the @RequestFilter annotation.

  • RoutingRule('/', AutoDiscoveringRoutingTable(self.registry, self.root_package_name))

    This is where the reflectively declared routes are registered. Without this rule, @Resource, @GET, @POST, ... annotations will not be parsed. Edit the prefix path to your liking.

Filtering rules

While additional request filters can be added to all requests by using the @RequestFilter annotation, specific filtering rules can be added to apply filters to specific routes only. The FilteringRule rule uses a path pattern which is used to select which filters to apply on any given incoming request. The pattern can either be given using a simple *-style wildcard, or using a regexp pattern.

from jivago.config.router.filtering.filtering_rule import FilteringRule

# Applies to all subpaths of "/users/". DOES NOT apply to "/users" itself.
FilteringRule("/users/*", [MyFilter])

# Only applies to "/users", and nothing else.
FilteringRule("/users", [MyFilter])

# Applies to "/users" and subpaths of "/users/...".
FilteringRule("/users*", [MyFilter])

# Applies to all requests matching regexp.
# First parameter is not used when regex_pattern is supplied.
FilteringRule(None, [MySpecialFilter], regex_pattern=r"^/users.*$")

Note that the simple URL pattern parameter is ignored when a regular expression is supplied.

CORS rules

CORS preflight behaviour can be tuned using CORS rules. The supplied prefix is used to define different behaviours for different sub-paths. The CORS rule does NOT support fuzzy pattern matching like the filtering rule. When multiple rules are applicable to an incoming request, only the longest one is applied.

from jivago.config.router.cors_rule import CorsRule

# Applies to all requests
CorsRule("/", {"Access-Control-Allow-Origin": '*'})

# Applies to all requests on a path which starts with '/users'
CorsRule("/users", {"Access-Control-Allow-Origin": 'api.example.com'})

By default, using the ``DebugJivagoContext`` adds a Access-Control-Allow-Origin: * rule at the root of the route hierarchy.