NAME
IO::K8s::Role::Routable - Role for building HTTP/gRPC routing rules
VERSION
version 1.108
SYNOPSIS
package My::Route;
use IO::K8s::APIObject api_version => 'gateway.networking.k8s.io/v1';
k8s spec => { Str => 1 };
with 'IO::K8s::Role::Routable';
sub _route_format { 'gateway' } # or 'traefik', 'ingress'
package main;
my $r = My::Route->new;
$r->add_hostname('example.com')
->add_backend('api-v1', port => 8080, weight => 90)
->add_path_match('/api', type => 'Prefix')
->add_header_match('X-Env', 'production');
# An ingress-formatted route gives every path its own backend.
use IO::K8s::Api::Networking::V1::Ingress;
my $ingress = IO::K8s::Api::Networking::V1::Ingress->new(
metadata => { name => 'web', namespace => 'prod' },
);
$ingress->add_path_match(
'/api', type => 'Prefix', service => 'api', port => 8080,
);
DESCRIPTION
This role provides fluent HTTP routing builders. A consuming class must declare a spec attribute as well as implement _route_format; the spec declaration in the synopsis permits IO::K8s::Role::SpecBuilder to create the route structure. The role dispatches on _route_format, which must return 'gateway', 'traefik', or 'ingress'.
Gateway API HTTPRoute and Traefik IngressRoute support the generic routing chain in the synopsis. Core Kubernetes Ingress has distinct backend slots: add_backend writes spec.defaultBackend for unmatched requests, while add_path_match requires service and port and writes that path's own backend. Thus an Ingress path must not rely on a preceding add_backend call for its backend.
The three formats produce different wire shapes:
'gateway'writes through IO::K8s::Role::SpecBuilder'sspec_*methods into aspecthat mirrors the HTTPRoute wire schema (hostnames,rules[].matches[].path,rules[].backendRefs) -- either a plain hash or a typed struct.'traefik'writes the same way into aspecthat mirrors the IngressRoute wire schema (routes[].matchas a Traefik expression,routes[].services[]).'ingress'builds typed IO::K8s::Api::Networking::V1::IngressSpec /IngressRule/HTTPIngressRuleValue/HTTPIngressPath/IngressBackend/IngressServiceBackend/ServiceBackendPortobjects.add_path_matchadds a typed path-specific backend, andadd_backendcontinues to set onlyspec.defaultBackend. The nested Ingress classes are loaded when the ingress branch first runs, not at composition time, so composing this role onto a Gateway API or Traefik Kind pulls none of them in.
add_path_match operates on the last rule in spec.rules for Gateway and Ingress, or the last route in spec.routes for Traefik. add_hostname creates an Ingress rule for each hostname; chain calls in declaration order therefore retain their natural top-to-bottom manifest order.
add_hostname
$route->add_hostname('example.com', 'api.example.com');
Adds hostnames the route should match. The role dispatches on _route_format:
'gateway'-- Gateway API HTTPRoute. Appends tospec.hostnames. Each hostname becomes its own entry on thehostnameslist.'traefik'-- Traefik IngressRoute. Adds a newroutesentry whosematchstring combines each hostname withHost(`...`), e.g.match => 'Host(`example.com`), Host(`api.example.com`)'.'ingress'-- core Kubernetes Ingress. Appends an IO::K8s::Api::Networking::V1::IngressRule per hostname withhost => $hostname.
Returns $self for chaining.
$route->add_hostname('example.com');
add_backend
$route->add_backend('api-v1', port => 8080, weight => 90);
Adds a backend the route should dispatch traffic to. name is required; port and weight are optional. Dispatch is per format:
'gateway'-- appends to the last rule'sbackendRefsas{ name, port, weight }.'traefik'-- appends to the last route'sservicesas{ name, port, weight }.'ingress'-- replacesspec.defaultBackendwith a typed IngressBackend / IngressServiceBackend / ServiceBackendPort chain, using the lastnameandport.
Returns $self for chaining.
$route->add_backend('api-v1', port => 8080, weight => 90);
add_path_match
# Gateway API or Traefik
$route->add_path_match('/api', type => 'Prefix');
# core Kubernetes Ingress
$ingress->add_path_match(
'/api', type => 'Prefix', service => 'api', port => 8080,
);
Adds a path match to the most recently added routing rule. type defaults to 'Prefix'. For Gateway API and Traefik, the shared vocabulary selects one of:
'Prefix'-- Gateway API{ path: { type: 'PathPrefix', value } }, TraefikPathPrefix(`...`).'Exact'-- Gateway API{ path: { type: 'Exact', value } }, TraefikPath(`...`).'Regex'-- Gateway API{ path: { type: 'RegularExpression', value } }, TraefikPathRegexp(`...`).
For 'ingress', this creates a typed IO::K8s::Api::Networking::V1::HTTPIngressPath with its own typed backend. service and port are required; port may be a numeric or named Service port. A numeric port is written as service.port.number, and a named port as service.port.name. Ingress accepts 'Prefix', 'Exact', and 'ImplementationSpecific'. 'Prefix' and 'Exact' require a defined path starting with /. 'ImplementationSpecific' permits an undefined or empty path, but a nonempty path must also start with /.
An Ingress call with a missing service or port, an unsupported path type, or an invalid 'Prefix', 'Exact', or nonempty 'ImplementationSpecific' path croaks before it mutates the object. add_backend remains independent: it writes spec.defaultBackend, the fallback for unmatched requests, and is never reused as a path backend.
Returns $self for chaining.
add_header_match
$route->add_header_match('X-Env', 'production');
Adds a header-based match to the most recently added routing rule. Gateway API appends to the last match's headers array as { name => $header, value => $value }; Traefik extends the route's match string with && Header(`<name>`, `<value>`). Core Ingress does not support header matching natively and the call is a no-op in that mode. Returns $self for chaining.
REQUIRED METHODS
_route_format
Must return 'gateway', 'traefik', or 'ingress'. The role dispatches all method bodies on this answer; a missing or unknown value is treated as a no-op.
SEE ALSO
IO::K8s::GatewayAPI, IO::K8s::Traefik, IO::K8s::Api::Networking::V1::IngressSpec, IO::K8s::APIObject
SUPPORT
Issues
Please report bugs and feature requests on GitHub at https://github.com/pplu/io-k8s-p5/issues.
CONTRIBUTING
Contributions are welcome! Please fork the repository and submit a pull request.
AUTHORS
Torsten Raudssus <getty@cpan.org>
Jose Luis Martinez Torres <jlmartin@cpan.org>
COPYRIGHT AND LICENSE
This software is Copyright (c) 2018-2026 by Jose Luis Martinez Torres <jlmartin@cpan.org>.
This is free software, licensed under:
The Apache License, Version 2.0, January 2004