NAME

Mojolicious::Plugin::OpenAPI - OpenAPI / Swagger plugin for Mojolicious

SYNOPSIS

Specification

{
  "paths": {
    "/pets": {
      "get": {
        "x-mojo-to": "pet#list",
        "summary": "Finds pets in the system",
        "responses": {
        "200": {
          "description": "Pet response",
          "schema": { "type": "array", "items": { "$ref": "#/definitions/Pet" } }
        },
        "default": {
          "description": "Unexpected error",
          "schema": { "$ref": "http://git.io/vcKD4#" }
        }
      }
    }
  }
}

The important 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.

"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});

Application

package Myapp;
use Mojolicious;

sub register {
  my $app = shift;
  $app->plugin("OpenAPI" => {url => "myapi.json"});
}

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 controller input and output will only be validated if the "openapi.input" and "reply.openapi" methods are used.

DESCRIPTION

Mojolicious::Plugin::OpenAPI will replace Mojolicious::Plugin::Swagger2.

This plugin is currently EXPERIMENTAL.

HELPERS

openapi.input

$hash = $c->openapi->input;

Returns the data which has been validated by the in OpenAPI specification.

openapi.spec

$hash = $c->openapi->spec;

Returns the OpenAPI specification for the current route:

{
  "paths": {
    "/pets": {
      "get": {
        // This datastructure
      }
    }
  }
}

Note: This might return a JSON pointer in the future.

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);
$c->reply->openapi;

Will validate $output before passing it on to "render" in Mojolicious::Controller. Calling this helper without any arguments will cause auto-rendering of input errors. See "SYNOPSIS" for example.

METHODS

register

$self->register($app, \%config);

Loads the OpenAPI specification, validates it and add routes to $app. It will also set up "HELPERS". %config can have:

{
  coerce    => 0,                           # default: 1
  log_level => "debug",                     # default: warn
  route     => $app->routes->under(...)     # not required
  url       => "path/to/specification.json" # required
}

route can be specified in case you want to have a protected API.

See "coerce" in JSON::Validator for possible values that coerce can take.

See "schema" in JSON::Validator for the different url formats that is accepted. Note that relative paths will be relative to "home" in Mojo.

TODO

  • Add WebSockets support.

  • Add support for /api.html (human readable format)

  • 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.