File: README.md

package info (click to toggle)
libmojolicious-plugin-openapi-perl 2.12-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 620 kB
  • sloc: perl: 1,190; makefile: 4
file content (304 lines) | stat: -rw-r--r-- 10,141 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
# 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->validation->param("body")};

      # 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
    plugin OpenAPI => {url => "data:///api.json"};
    app->start;

    __DATA__
    @@ api.json
    {
      "swagger" : "2.0",
      "info" : { "version": "0.8", "title" : "Pets" },
      "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::Tutorial](https://metacpan.org/pod/Mojolicious::Plugin::OpenAPI::Guides::Tutorial) for a tutorial on how to
write a "full" app with application class and controllers.

# DESCRIPTION

[Mojolicious::Plugin::OpenAPI](https://metacpan.org/pod/Mojolicious::Plugin::OpenAPI) is [Mojolicious::Plugin](https://metacpan.org/pod/Mojolicious::Plugin) that add routes and
input/output validation to your [Mojolicious](https://metacpan.org/pod/Mojolicious) application based on a OpenAPI
(Swagger) specification.

Have a look at the ["SEE ALSO"](#see-also) for references to more documentation, or jump
right to the [tutorial](https://metacpan.org/pod/Mojolicious::Plugin::OpenAPI::Guides::Tutorial).

Currently v2 is very well supported, while v3 should be considered higly
EXPERIMENTAL. Note that testing out v3 requires [YAML::XS](https://metacpan.org/pod/YAML::XS) to be installed.

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::Validator::Error) 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.

Validated input parameters will be copied to
`Mojolicious::Controller/validation`, which again can be extracted by the
"name" in the parameters list from the spec. Example:

    # specification:
    "parameters": [{"in": "body", "name": "whatever", "schema": {"type": "object"}}],

    # controller
    my $body = $c->validation->param("whatever");

## openapi.valid\_input

    $c = $c->openapi->valid_input;

Returns the [Mojolicious::Controller](https://metacpan.org/pod/Mojolicious::Controller) 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::Plugin::OpenAPI) 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::Routes::Route) object for all the OpenAPI endpoints.

## validator

    $jv = $openapi->validator;

Holds a [JSON::Validator::OpenAPI::Mojolicious](https://metacpan.org/pod/JSON::Validator::OpenAPI::Mojolicious) 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::Validator#coerce) for possible values that `coerce` can take.

Default: 1

### 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::Tutorial](https://metacpan.org/pod/Mojolicious::Plugin::OpenAPI::Guides::Tutorial#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::Plugin::OpenAPI::Cors),
[Mojolicious::Plugin::OpenAPI::SpecRenderer](https://metacpan.org/pod/Mojolicious::Plugin::OpenAPI::SpecRenderer) and
[Mojolicious::Plugin::OpenAPI::Security](https://metacpan.org/pod/Mojolicious::Plugin::OpenAPI::Security).

    $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".

### 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::Validator#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`.

# 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::OpenAPI::Guides::Tutorial](https://metacpan.org/pod/Mojolicious::Plugin::OpenAPI::Guides::Tutorial)
- [Mojolicious::Plugin::OpenAPI::Cors](https://metacpan.org/pod/Mojolicious::Plugin::OpenAPI::Cors)
- [Mojolicious::Plugin::OpenAPI::Security](https://metacpan.org/pod/Mojolicious::Plugin::OpenAPI::Security)
- [Mojolicious::Plugin::OpenAPI::SpecRenderer](https://metacpan.org/pod/Mojolicious::Plugin::OpenAPI::SpecRenderer)
- [http://thorsen.pm/perl/programming/2015/07/05/mojolicious-swagger2.html](http://thorsen.pm/perl/programming/2015/07/05/mojolicious-swagger2.html).
- [OpenAPI specification](https://openapis.org/specification)