NAME
Punk::Mount::OpenAPI - the api mount: spec-first operations
SYNOPSIS
my $v1 = under '/v1' => 'API::Auth#bearer';
my $api = $v1->api('openapi.json' => {
controller_ns => 'MyApp::Controller::API', # the default
under => { '/books/manage' => 'API::Auth#admin' },
security => { session => 'API::Auth#session' },
});
DESCRIPTION
An api mount compiles an OpenAPI 3.1 document through Open::API and dispatches each operation to the controller method named after its operationId. Everything resolves at to_app:
every class under
controller_ns(defaultMyApp::Controller::API) is loaded and operationIds mapped to the one class implementing each - two implementers croak, none croaks (unlessstub => 1, which answers 501 per request instead); thehandlersoption overrides per operationId with a coderef or target string;the spec's security requirements compile to a generated guard per operation from the
security => { scheme => checker }map - alternatives are OR, schemes within one are AND, results land in$c->stash->{auth}, failure answers 401 before any validation. A required scheme with no checker croaks at boot;the
underoption assigns extra guards by spec-path prefix (longest prefix wins), appended after the mount scope's own guards.
Per request the pipeline is: route ($api->match, one C call), guard chain (a 401/redirect costs no body read), max_body_size check (413), $api->validate_request (one C call; failures answer 400 with the same {errors=>[...]} shape as Open::API::Plack), then the controller with $c->openapi holding the typed parameters and $c->param reading them first.
METHODS
The mount is an internal object: the api keyword returns it and the framework drives it.
new(spec => $spec, opts => \%opts, prefix => $prefix, guards => \@guards)
Records a mount; nothing is resolved until "compile".
compile($app, $resolve)
Run at to_app: resolves every operationId to its controller method and freezes each operation's guard chain (the scope's guards, then the spec's security requirement, then the under guards). Croaks on anything unresolved. Returns the mount.
dispatch($c, $before, $op_id, \%captures)
Runs one matched operation for a request: the before_dispatch hooks, the guards, the body-size check, validation and the controller. Returns ($ret, $err) for the application's response path.
prefix
The path the mount is under.
api
The compiled Open::API.
ops
The compiled operations, a hashref keyed by operationId.
max_body_size
The body ceiling in bytes; see "OPTIONS".
on_error
The mount's own error handler, or undef.
OPTIONS
controller_ns, handlers, under, security, max_body_size (default 1048576), on_error (mount-level override), stub.
SEE ALSO
Punk, Open::API, Open::API::Plack.
AUTHOR
LNATION <email@lnation.org>
LICENSE AND COPYRIGHT
This software is Copyright (c) 2026 by LNATION <email@lnation.org>.
This is free software, licensed under:
The Artistic License 2.0 (GPL Compatible)