# NAME Mojolicious::Plugin::OpenAPI - OpenAPI / Swagger plugin for Mojolicious # SYNOPSIS use Mojolicious::Lite; # Will be moved under "basePath", resulting in "POST /api/echo" post "/echo" => sub { # Validate input request or return an error document my $c = shift->openapi->valid_input or return; # Generate some data my $data = {body => $c->req->json}; # Validate the output response and render it to the user agent # using a custom "openapi" handler. $c->render(openapi => $data); }, "echo"; # Load specification and start web server # Use "v3" instead of "v2" for "schema" if you are using OpenAPI v3 plugin OpenAPI => {url => "data:///spec.json", schema => "v2"}; app->start; __DATA__ @@ spec.json { "swagger" : "2.0", "info" : { "version": "0.8", "title" : "Echo Service" }, "schemes" : [ "http" ], "basePath" : "/api", "paths" : { "/echo" : { "post" : { "x-mojo-name" : "echo", "parameters" : [ { "in": "body", "name": "body", "schema": { "type" : "object" } } ], "responses" : { "200": { "description": "Echo response", "schema": { "type": "object" } } } } } } } See [Mojolicious::Plugin::OpenAPI::Guides::OpenAPIv2](https://metacpan.org/pod/Mojolicious%3A%3APlugin%3A%3AOpenAPI%3A%3AGuides%3A%3AOpenAPIv2) or [Mojolicious::Plugin::OpenAPI::Guides::OpenAPIv3](https://metacpan.org/pod/Mojolicious%3A%3APlugin%3A%3AOpenAPI%3A%3AGuides%3A%3AOpenAPIv3) for tutorials on how to write a "full" app with application class and controllers. # DESCRIPTION [Mojolicious::Plugin::OpenAPI](https://metacpan.org/pod/Mojolicious%3A%3APlugin%3A%3AOpenAPI) is [Mojolicious::Plugin](https://metacpan.org/pod/Mojolicious%3A%3APlugin) that add routes and input/output validation to your [Mojolicious](https://metacpan.org/pod/Mojolicious) application based on a OpenAPI (Swagger) specification. This plugin supports both version [2.0](#schema) and [3.x](#schema), though 3.x _might_ have some missing features. Have a look at the ["SEE ALSO"](#see-also) for references to more documentation. Please report in [issues](https://github.com/jhthorsen/json-validator/issues) or open pull requests to enhance the 3.0 support. # HELPERS ## openapi.spec $hash = $c->openapi->spec($json_pointer) $hash = $c->openapi->spec("/info/title") $hash = $c->openapi->spec; Returns the OpenAPI specification. A JSON Pointer can be used to extract a given section of the specification. The default value of `$json_pointer` will be relative to the current operation. Example: { "paths": { "/pets": { "get": { // This datastructure is returned by default } } } } ## openapi.validate @errors = $c->openapi->validate; Used to validate a request. `@errors` holds a list of [JSON::Validator::Error](https://metacpan.org/pod/JSON%3A%3AValidator%3A%3AError) objects or empty list on valid input. Note that this helper is only for customization. You probably want ["openapi.valid\_input"](#openapi-valid_input) in most cases. ## openapi.valid\_input $c = $c->openapi->valid_input; Returns the [Mojolicious::Controller](https://metacpan.org/pod/Mojolicious%3A%3AController) object if the input is valid or automatically render an error document if not and return false. See ["SYNOPSIS"](#synopsis) for example usage. # HOOKS [Mojolicious::Plugin::OpenAPI](https://metacpan.org/pod/Mojolicious%3A%3APlugin%3A%3AOpenAPI) will emit the following hooks on the [application](https://metacpan.org/pod/Mojolicious) object. ## openapi\_routes\_added Emitted after all routes have been added by this plugin. $app->hook(openapi_routes_added => sub { my ($openapi, $routes) = @_; for my $route (@$routes) { ... } }); This hook is EXPERIMENTAL and subject for change. # RENDERER This plugin register a new handler called `openapi`. The special thing about this handler is that it will validate the data before sending it back to the user agent. Examples: $c->render(json => {foo => 123}); # without validation $c->render(openapi => {foo => 123}); # with validation This handler will also use ["renderer"](#renderer) to format the output data. The code below shows the default ["renderer"](#renderer) which generates JSON data: $app->plugin( OpenAPI => { renderer => sub { my ($c, $data) = @_; return Mojo::JSON::encode_json($data); } } ); # ATTRIBUTES ## route $route = $openapi->route; The parent [Mojolicious::Routes::Route](https://metacpan.org/pod/Mojolicious%3A%3ARoutes%3A%3ARoute) object for all the OpenAPI endpoints. ## validator $jv = $openapi->validator; Holds a [JSON::Validator::OpenAPI::Mojolicious](https://metacpan.org/pod/JSON%3A%3AValidator%3A%3AOpenAPI%3A%3AMojolicious) object. # METHODS ## register $openapi = $openapi->register($app, \%config); $openapi = $app->plugin(OpenAPI => \%config); Loads the OpenAPI specification, validates it and add routes to [$app](https://metacpan.org/pod/Mojolicious). It will also set up ["HELPERS"](#helpers) and adds a [before\_render](https://metacpan.org/pod/Mojolicious#before_render) hook for auto-rendering of error documents. The return value is the object instance, which allow you to access the ["ATTRIBUTES"](#attributes) after you load the plugin. `%config` can have: ### allow\_invalid\_ref The OpenAPI specification does not allow "$ref" at every level, but setting this flag to a true value will ignore the $ref check. Note that setting this attribute is discourage. ### coerce See ["coerce" in JSON::Validator](https://metacpan.org/pod/JSON%3A%3AValidator#coerce) for possible values that `coerce` can take. Default: booleans,numbers,strings The default value will include "defaults" in the future, once that is stable enough. ### default\_response\_codes A list of response codes that will get a `"$ref"` pointing to "#/definitions/DefaultResponse", unless already defined in the spec. "DefaultResponse" can be altered by setting ["default\_response\_name"](#default_response_name). The default response code list is the following: 400 | Bad Request | Invalid input from client / user agent 401 | Unauthorized | Used by Mojolicious::Plugin::OpenAPI::Security 404 | Not Found | Route is not defined 500 | Internal Server Error | Internal error or failed output validation 501 | Not Implemented | Route exists, but the action is not implemented Note that more default codes might be added in the future if required by the plugin. ### default\_response\_name The name of the "definition" in the spec that will be used for ["default\_response\_codes"](#default_response_codes). The default value is "DefaultResponse". See ["Default response schema" in Mojolicious::Plugin::OpenAPI::Guides::OpenAPIv2](https://metacpan.org/pod/Mojolicious%3A%3APlugin%3A%3AOpenAPI%3A%3AGuides%3A%3AOpenAPIv2#Default-response-schema) for more details. ### log\_level `log_level` is used when logging invalid request/response error messages. Default: "warn". ### plugins A list of OpenAPI classes to extend the functionality. Default is: [Mojolicious::Plugin::OpenAPI::Cors](https://metacpan.org/pod/Mojolicious%3A%3APlugin%3A%3AOpenAPI%3A%3ACors), [Mojolicious::Plugin::OpenAPI::SpecRenderer](https://metacpan.org/pod/Mojolicious%3A%3APlugin%3A%3AOpenAPI%3A%3ASpecRenderer) and [Mojolicious::Plugin::OpenAPI::Security](https://metacpan.org/pod/Mojolicious%3A%3APlugin%3A%3AOpenAPI%3A%3ASecurity). $app->plugin(OpenAPI => {plugins => [qw(+Cors +SpecRenderer +Security)]}); You can load your own plugins by doing: $app->plugin(OpenAPI => {plugins => [qw(+SpecRenderer My::Cool::OpenAPI::Plugin)]}); ### renderer See ["RENDERER"](#renderer). ### route `route` can be specified in case you want to have a protected API. Example: $app->plugin(OpenAPI => { route => $app->routes->under("/api")->to("user#auth"), url => $app->home->rel_file("cool.api"), }); ### schema Can be used to set a different schema, than the default OpenAPI 2.0 spec. Example values: "http://swagger.io/v2/schema.json", "v2" or "v3". See also [Mojolicious::Plugin::OpenAPI::Guides::OpenAPIv2](https://metacpan.org/pod/Mojolicious%3A%3APlugin%3A%3AOpenAPI%3A%3AGuides%3A%3AOpenAPIv2) and [Mojolicious::Plugin::OpenAPI::Guides::OpenAPIv3](https://metacpan.org/pod/Mojolicious%3A%3APlugin%3A%3AOpenAPI%3A%3AGuides%3A%3AOpenAPIv3). ### spec\_route\_name Name of the route that handles the "basePath" part of the specification and serves the specification. Defaults to "x-mojo-name" in the specification at the top level. ### url See ["schema" in JSON::Validator](https://metacpan.org/pod/JSON%3A%3AValidator#schema) for the different `url` formats that is accepted. `spec` is an alias for "url", which might make more sense if your specification is written in perl, instead of JSON or YAML. ### version\_from\_class Can be used to overridden `/info/version` in the API specification, from the return value from the `VERSION()` method in `version_from_class`. This will only have an effect if "version" is "0". Defaults to the current `$app`. # AUTHORS Henrik Andersen Ilya Rassadin Jan Henning Thorsen Joel Berger # COPYRIGHT AND LICENSE Copyright (C) Jan Henning Thorsen This program is free software, you can redistribute it and/or modify it under the terms of the Artistic License version 2.0. # SEE ALSO - [Mojolicious::Plugin::OpenAPI::Guides::OpenAPIv2](https://metacpan.org/pod/Mojolicious%3A%3APlugin%3A%3AOpenAPI%3A%3AGuides%3A%3AOpenAPIv2) Guide for how to use this plugin with OpenAPI version 2.0 spec. - [Mojolicious::Plugin::OpenAPI::Guides::OpenAPIv3](https://metacpan.org/pod/Mojolicious%3A%3APlugin%3A%3AOpenAPI%3A%3AGuides%3A%3AOpenAPIv3) Guide for how to use this plugin with OpenAPI version 3.0 spec. - [Mojolicious::Plugin::OpenAPI::Cors](https://metacpan.org/pod/Mojolicious%3A%3APlugin%3A%3AOpenAPI%3A%3ACors) Plugin to add Cross-Origin Resource Sharing (CORS). - [Mojolicious::Plugin::OpenAPI::Security](https://metacpan.org/pod/Mojolicious%3A%3APlugin%3A%3AOpenAPI%3A%3ASecurity) Plugin for handling security definitions in your schema. - [Mojolicious::Plugin::OpenAPI::SpecRenderer](https://metacpan.org/pod/Mojolicious%3A%3APlugin%3A%3AOpenAPI%3A%3ASpecRenderer) Plugin for exposing your spec in human readble or JSON format. - [https://www.openapis.org/](https://www.openapis.org/) Official OpenAPI website.