1Mojolicious::Plugin::OpUesneArPIC:oM:noGtjuroiildbieucsti:eo:duOspP:ee:nrPAllPuIDgvoi2cn(u:3m:)eOnpteantAiPoIn::Guides::OpenAPIv2(3)
2
3
4
6 Mojolicious::Plugin::OpenAPI::Guides::OpenAPIv2 - Mojolicious <3
7 OpenAPI v2 (Swagger)
8
10 This guide will give you an introduction to how to use
11 Mojolicious::Plugin::OpenAPI with OpenAPI version v2.
12
14 Specification
15 This plugin reads an OpenAPI specification
16 <https://openapis.org/specification> and generate routes and
17 input/output rules from it. See JSON::Validator for supported schema
18 file formats.
19
20 {
21 "swagger": "2.0",
22 "info": { "version": "1.0", "title": "Some awesome API" },
23 "basePath": "/api",
24 "paths": {
25 "/pets": {
26 "get": {
27 "operationId": "getPets",
28 "x-mojo-name": "get_pets",
29 "x-mojo-to": "pet#list",
30 "summary": "Finds pets in the system",
31 "parameters": [
32 {"in": "body", "name": "body", "schema": {"type": "object"}},
33 {"in": "query", "name": "age", "type": "integer"}
34 ],
35 "responses": {
36 "200": {
37 "description": "Pet response",
38 "schema": {
39 "type": "object",
40 "properties": {
41 "pets": {
42 "type": "array",
43 "items": { "type": "object" }
44 }
45 }
46 }
47 }
48 }
49 }
50 }
51 }
52 }
53
54 The complete HTTP request for getting the "pet list" will be "GET
55 /api/pets" The first part of the path ("/api") comes from "basePath",
56 the second part comes from the keys under "paths", and the HTTP method
57 comes from the keys under "/pets".
58
59 The different parts of the specification can also be retrieved as JSON
60 using the "OPTIONS" HTTP method. Example:
61
62 OPTIONS /api/pets
63 OPTIONS /api/pets?method=get
64
65 Note that the use of "OPTIONS" is EXPERIMENTAL, and subject to change.
66
67 Here are some more details about the different keys:
68
69 • swagger and info
70
71 These two sections are required to make the specification valid.
72 Check out
73 <https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md>
74 for a complete reference to the specification.
75
76 • host, schemes, consumes, produces, security and securityDefinitions
77
78 These keys are currently not in use. "host" will be replaced by the
79 "Host" header in the request. The rest of the keys are currently not
80 in use.
81
82 Submit an issue <https://github.com/jhthorsen/mojolicious-plugin-
83 openapi/issues> if you have ideas on what to use these keys for.
84
85 • basePath
86
87 The "basePath" will also be used to add a route that renders back the
88 specification either as JSON or HTML. Examples:
89
90 • http://example.com/api.html
91
92 Retrieve the expanded version of the API in human readable format.
93 The formatting is currently a bit rough, but should be easier than
94 reading the JSON spec.
95
96 • http://example.com/api.json
97
98 Retrieve the expanded version of the API, useful for JavaScript
99 clients and other client side applications.
100
101 • parameters and responses
102
103 "parameters" and "responses" will be used to define input and output
104 validtion rules, which is used by "openapi.input" in
105 Mojolicious::Plugin::OpenAPI and when rendering the response back to
106 the client, using "render(openapi => ...)".
107
108 Have a look at "RENDERER" in Mojolicious::Plugin::OpenAPI for more
109 details about output rendering.
110
111 • operationId and x-mojo-name
112
113 See "Route names".
114
115 • x-mojo-placeholder
116
117 "x-mojo-placeholder" can be used inside a parameter definition to
118 instruct Mojolicious to parse a path part in a certain way. Example:
119
120 "parameters": [
121 {
122 "x-mojo-placeholder": "#",
123 "in": "path",
124 "name": "email",
125 "type": "string"
126 }
127 ]
128
129 See Mojolicious::Guides::Routing for more information about
130 "standard", "relaxed" and "wildcard" placeholders. The default is to
131 use the "standard" ("/:foo") placeholder.
132
133 • x-mojo-to
134
135 The non-standard part in the spec above is "x-mojo-to". The "x-mojo-
136 to" key can be either a plain string, object (hash) or an array. The
137 string and hash will be passed directly to "to" in
138 Mojolicious::Routes::Route, while the array ref will be flatten.
139 Examples:
140
141 "x-mojo-to": "pet#list"
142 $route->to("pet#list");
143
144 "x-mojo-to": {"controller": "pet", "action": "list", "foo": 123}
145 $route->to({controller => "pet", action => "list", foo => 123);
146
147 "x-mojo-to": ["pet#list", {"foo": 123}]
148 $route->to("pet#list", {foo => 123});
149
150 Application
151 package Myapp;
152 use Mojo::Base "Mojolicious";
153
154 sub startup {
155 my $app = shift;
156 $app->plugin("OpenAPI" => {url => $app->home->rel_file("myapi.json")});
157 }
158
159 1;
160
161 The first thing in your code that you need to do is to load this plugin
162 and the "Specification". See "register" in Mojolicious::Plugin::OpenAPI
163 for information about what the plugin config can be.
164
165 See also "SYNOPSIS" in Mojolicious::Plugin::OpenAPI for example
166 Mojolicious::Lite application.
167
168 Controller
169 package Myapp::Controller::Pet;
170 use Mojo::Base "Mojolicious::Controller";
171
172 sub list {
173
174 # Do not continue on invalid input and render a default 400
175 # error document.
176 my $c = shift->openapi->valid_input or return;
177
178 # You might want to introspect the specification for the current route
179 my $spec = $c->openapi->spec;
180 unless ($spec->{'x-opening-hour'} == (localtime)[2]) {
181 return $c->render(openapi => [], status => 498);
182 }
183
184 my $age = $c->param("age");
185 my $body = $c->req->json;
186
187 # $output will be validated by the OpenAPI spec before rendered
188 my $output = {pets => [{name => "kit-e-cat"}]};
189 $c->render(openapi => $output);
190 }
191
192 1;
193
194 The input will be validated using "openapi.valid_input" in
195 Mojolicious::Plugin::OpenAPI while the output is validated through then
196 openapi handler.
197
198 Route names
199 Routes will get its name from either "x-mojo-name" or from
200 "operationId" if defined in the specification.
201
202 The route name can also be used the other way around, to find already
203 defined routes. This is especially useful for Mojolicious::Lite apps.
204
205 Note that if spec_route_name then all the route names will have that
206 value as prefix:
207
208 spec_route_name = "my_cool_api"
209 operationId or x-mojo-name = "Foo"
210 Route name = "my_cool_api.Foo"
211
212 You can also set "x-mojo-name" in the spec, instead of passing
213 spec_route_name to plugin():
214
215 {
216 "swagger": "2.0",
217 "info": { "version": "1.0", "title": "Some awesome API" },
218 "x-mojo-name": "my_cool_api"
219 }
220
221 Default response schema
222 A default response definition will be added to the API spec, unless
223 it's already defined. This schema will at least be used for invalid
224 input (400 - Bad Request) and invalid output (500 - Internal Server
225 Error), but can also be used in other cases.
226
227 See "default_response_codes" in Mojolicious::Plugin::OpenAPI and
228 "default_response_name" in Mojolicious::Plugin::OpenAPI for more
229 details on how to configure these settings.
230
231 The response schema will be added to your spec like this, unless
232 already defined:
233
234 {
235 ...
236 "definitions": {
237 ...
238 "DefaultResponse": {
239 "type": "object",
240 "required": ["errors"],
241 "properties": {
242 "errors": {
243 "type": "array",
244 "items": {
245 "type": "object",
246 "required": ["message"],
247 "properties": {"message": {"type": "string"}, "path": {"type": "string"}}
248 }
249 }
250 }
251 }
252 }
253 }
254
255 The "errors" key will contain one element for all the invalid data, and
256 not just the first one. The useful part for a client is mostly the
257 "path", while the "message" is just to add some human readable debug
258 information for why this request/response failed.
259
260 Rendering binary data
261 Rendering assets and binary data should be accomplished by using the
262 standard Mojolicious tools:
263
264 sub get_image {
265 my $c = shift->openapi->valid_input or return;
266 my $asset = Mojo::Asset::File->new(path => "image.jpeg");
267
268 $c->res->headers->content_type("image/jpeg");
269 $c->reply->asset($asset);
270 }
271
273 Mojolicious::Plugin::OpenAPI, <https://openapis.org/specification>.
274
275
276
277perl v5.32.1 Mojoli2c0i2o1u-s0:1:-P3l1ugin::OpenAPI::Guides::OpenAPIv2(3)