Mojolicious-Plugin-OpenAPI-Modern

Mojolicious plugin providing access to an OpenAPI document and parser

OTHER License

Stars
3
Committers
1

=pod

=encoding UTF-8

=head1 NAME

Mojolicious::Plugin::OpenAPI::Modern - Mojolicious plugin providing access to an OpenAPI document and parser

=head1 VERSION

version 0.012

=head1 SYNOPSIS

$app->config({ openapi => { document_filename => 'data/openapi.yaml', after_response => sub ($c) { ... }, }, ... });

$app->plugin('OpenAPI::Modern', $app->config->{openapi});

in a controller...

my $result = $c->openapi->validate_request($c->req);

=head1 DESCRIPTION

This L plugin makes an LOpenAPI::Modern object available to the application.

There are many features to come.

=for stopwords openapi operationId subref

=head1 CONFIGURATION OPTIONS

=head2 schema

The literal, unblessed Perl data structure containing the OpenAPI document. See LOpenAPI::Modern/openapi_schema; passed to the LOpenAPI::Modern constructor. Only used if L</openapi_obj> is not provided.

=head2 document_filename

A filename indicating from where to load the OpenAPI document. Supports YAML and json file formats. Only used if L is not provided; also passed to the LOpenAPI::Modern constructor as C<openapi_uri>. Only used if L</openapi_obj> is not provided.

=head2 openapi_obj

An LOpenAPI::Modern object to use

=head2 after_response

A subref which runs after the response has been finalized, to allow you to perform validation on it. You B mutate the response here, nor swap it out for a different response, so use this only for telemetry and logging.

my $after_response = sub ($c) { my $result = $c->validate_response; if ($result) { $c->log->debug('response is valid'); } else { # see JSON::Schema::Modern::Result for different output formats $c->log->error("response is invalid:\n", $result); } };

=head1 METHODS

=head2 register

Instantiates an LOpenAPI::Modern object and provides an accessor to it.

=head1 HELPERS

These methods are made available on the C<$c> object (the invocant of all controller methods, and therefore other helpers).

=head2 openapi

The LOpenAPI::Modern object; it holds your OpenAPI specification and is reused between requests.

=head2 validate_request

my $result = $c->openapi->validate_request;

Passes C<< $c->req >> to LOpenAPI::Modern/validate_request and returns a LJSON::Schema::Modern::Result object.

Note that the matching LMojo::Routes::Route object for this request is I used to find the OpenAPI path-item that corresponds to this request: only information in the request URI itself is used (although some information in the route may be used in future features).

You might want to define an C route action that calls C<validate_request> and short-circuits with an HTTP 400 response on validation failure.

=head2 validate_response

my $result = $c->openapi->validate_response;

Passes C<< $c->res >> and C<< $c->req >> to LOpenAPI::Modern/validate_response and returns a LJSON::Schema::Modern::Result object.

As this can only be called in the parts of the dispatch flow where the response has already been rendered and finalized, a hook has been set up for you; you can access it by providing a subref to the L</after_response> configuration value:

$app->config->{openapi}{after_response} //= sub ($c) { my $result = $c->validate_response; # ... do something with the validation result };

Note that the matching LMojo::Routes::Route object for this request is I used to find the OpenAPI path-item that corresponds to this request and response: only information in the request URI itself is used (although some information in the route may be used in future features).

=head1 STASH VALUES

This plugin stores all its data under the C hashref, e.g.:

my $operation_id = $c->stash->{openapi}{operation_id};

Keys starting with underscore are for I and should not be relied upon to behave consistently across release versions. Values that may be used by controllers and templates are:

=over 4

=item *

C<path_template>: Set by the first call to L</validate_request> or L</validate_response>. A string representing the request URI, with placeholders in braces (e.g. C</pets/{petId}>); see Lhttps://spec.openapis.org/oas/v3.1.0#paths-object.

=item *

C<path_captures>: Set by the first call to L</validate_request> or L</validate_response>. A hashref mapping placeholders in the path to their actual values in the request URI.

=item *

C<operation_id>: Set by the first call to L</validate_request> or L</validate_response>. Contains the corresponding L<operationId|https://swagger.io/docs/specification/paths-and-operations/#operationid> of the current endpoint.

=item *

C: Set by the first call to L</validate_request> or L</validate_response>. The HTTP method used by the request, lower-cased.

=back

=head1 SEE ALSO

=over 4

=item *

LOpenAPI::Modern

=item *

LTest::Mojo::Role::OpenAPI::Modern

=item *

LJSON::Schema::Modern::Document::OpenAPI

=item *

LJSON::Schema::Modern

=item *

Lhttps://json-schema.org

=item *

Lhttps://www.openapis.org/

=item *

Lhttps://learn.openapis.org/

=item *

Lhttps://spec.openapis.org/oas/v3.1.0

=back

=head1 SUPPORT

Bugs may be submitted through Lhttps://github.com/karenetheridge/Mojolicious-Plugin-OpenAPI-Modern/issues.

I am also usually active on irc, as 'ether' at C<irc.perl.org> and C<irc.libera.chat>.

You can also find me on the L<JSON Schema Slack server|https://json-schema.slack.com> and L<OpenAPI Slack server|https://open-api.slack.com>, which are also great resources for finding help.

=head1 AUTHOR

Karen Etheridge [email protected]

=head1 COPYRIGHT AND LICENCE

This software is copyright (c) 2021 by Karen Etheridge.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.

=cut