NAME Mojolicious::Plugin::OpenAPI - OpenAPI / Swagger plugin for Mojolicious SYNOPSIS Specification This plugin reads an OpenAPI specification and generate routes and input/output rules from it. See JSON::Validator for supported schema formats. { "basePath": "/api", "paths": { "/pets": { "get": { "x-mojo-to": "pet#list", "summary": "Finds pets in the system", "parameters": [], "responses": { "200": { "description": "Pet response", "schema": { "type": "array", "items": { "type": "object" } } }, "default": { "description": "Unexpected error", "schema": { "$ref": "http://git.io/vcKD4#" } } } } } } } The non-standard part in the spec above is "x-mojo-to". The "x-mojo-to" key can either a plain string, object (hash) or an array. The string and hash will be passed directly to "to" in Mojolicious::Routes::Route, while the array ref, will be flattened first. Examples: "x-mojo-to": "pet#list" $route->to("pet#list"); "x-mojo-to": {"controller": "pet", "action": "list", "foo": 123} $route->to({controller => "pet", action => "list", foo => 123); "x-mojo-to": ["pet#list", {"foo": 123}] $route->to("pet#list", {foo => 123}); The complete HTTP request for getting the "pet list" will be "GET /api/pets" The first part of the path ("/api") comes from "basePath", the second part comes from the key under "paths", and the HTTP method comes from the key under "/pets". "parameters" and "responses" will be used to define rules for input and output. Application package Myapp; use Mojolicious; sub startup { my $app = shift; $app->plugin("OpenAPI" => {url => $app->home->rel_file("myapi.json")}); } The first thing in your code that you need to do is to load this plugin and the "Specification". See "register" for information about what the plugin config can be, in addition to "url". Controller package Myapp::Controller::Pet; sub list { my $c = shift; # You might want to introspect the specification for the current route my $spec = $c->openapi->spec; unless ($spec->{'x-opening-hour'} == (localtime)[2]) { return $c->reply->openapi([], 498); } # $input will be a hash ref if validated and undef on invalid input my $input = $c->openapi->input or return; # $output will be validated by the OpenAPI spec before rendered my $output = {pets => [{name => "kit-e-cat"}]}; $c->reply->openapi($output, 200); } The input and output to the action will only be validated if the "openapi.input" and "reply.openapi" methods are used. All OpenAPI powered actions will have auto-rendering enabled, which means that the "return;" above will render an error document. DESCRIPTION Mojolicious::Plugin::OpenAPI will replace Mojolicious::Plugin::Swagger2. This plugin is currently EXPERIMENTAL. HELPERS openapi.input $hash = $c->openapi->input; Returns the request parameters if they are valid, and "undef" on invalid input. openapi.spec $hash = $c->openapi->spec; Returns the OpenAPI specification for the current route. Example: { "paths": { "/pets": { "get": { // This datastructure is returned } } } } openapi.validate # validate request @errors = $c->openapi->validate; # validate response @errors = $c->openapi->validate($output, $http_status); Used to validate input or output data. Request validation is always done by "openapi.input". reply.openapi $c->reply->openapi(\%output, $http_status); Will validate %output before passing it on to "render" in Mojolicious::Controller. Note that %output will be passed on using the format key in stash, which defaults to "json". This also goes for auto-rendering. Example: my $format = $c->stash("format") || "json"; $c->render($format => \%output); METHODS register $self->register($app, \%config); Loads the OpenAPI specification, validates it and add routes to $app. It will also set up "HELPERS" and adds a before_render hook for auto-rendering of error documents. %config can have: * coerce See "coerce" in JSON::Validator for possible values that "coerce" can take. Default: 1 * log_level "log_level" is used when logging invalid request/response error messages. Default: "warn". * 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"), }); * url See "schema" in JSON::Validator for the different "url" formats that is accepted. TODO This plugin is still a big rough on the edges, but I decided to release it on CPAN so people can start playing around with it. * Add WebSockets support . * Add support for /api.html (human readable documentation) * Never add support for "x-mojo-around-action", but possibly "before action". AUTHOR Jan Henning Thorsen COPYRIGHT AND LICENSE Copyright (C) 2016, 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::Swagger2.