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}, ["format": ["json"]]]
148 $route->to("pet#list", {foo => 123});
149 $route->pattern->constraints->{format} = ["json"];
150
151 Application
152 package Myapp;
153 use Mojo::Base "Mojolicious";
154
155 sub startup {
156 my $app = shift;
157 $app->plugin("OpenAPI" => {url => $app->home->rel_file("myapi.json")});
158 }
159
160 1;
161
162 The first thing in your code that you need to do is to load this plugin
163 and the "Specification". See "register" in Mojolicious::Plugin::OpenAPI
164 for information about what the plugin config can be.
165
166 See also "SYNOPSIS" in Mojolicious::Plugin::OpenAPI for example
167 Mojolicious::Lite application.
168
169 Controller
170 package Myapp::Controller::Pet;
171 use Mojo::Base "Mojolicious::Controller";
172
173 sub list {
174
175 # Do not continue on invalid input and render a default 400
176 # error document.
177 my $c = shift->openapi->valid_input or return;
178
179 # You might want to introspect the specification for the current route
180 my $spec = $c->openapi->spec;
181 unless ($spec->{'x-opening-hour'} == (localtime)[2]) {
182 return $c->render(openapi => [], status => 498);
183 }
184
185 my $age = $c->param("age");
186 my $body = $c->req->json;
187
188 # $output will be validated by the OpenAPI spec before rendered
189 my $output = {pets => [{name => "kit-e-cat"}]};
190 $c->render(openapi => $output);
191 }
192
193 1;
194
195 The input will be validated using "openapi.valid_input" in
196 Mojolicious::Plugin::OpenAPI while the output is validated through then
197 openapi handler.
198
199 Route names
200 Routes will get its name from either "x-mojo-name" or from
201 "operationId" if defined in the specification.
202
203 The route name can also be used the other way around, to find already
204 defined routes. This is especially useful for Mojolicious::Lite apps.
205
206 Note that if spec_route_name then all the route names will have that
207 value as prefix:
208
209 spec_route_name = "my_cool_api"
210 operationId or x-mojo-name = "Foo"
211 Route name = "my_cool_api.Foo"
212
213 You can also set "x-mojo-name" in the spec, instead of passing
214 spec_route_name to plugin():
215
216 {
217 "swagger": "2.0",
218 "info": { "version": "1.0", "title": "Some awesome API" },
219 "x-mojo-name": "my_cool_api"
220 }
221
222 Default response schema
223 A default response definition will be added to the API spec, unless
224 it's already defined. This schema will at least be used for invalid
225 input (400 - Bad Request) and invalid output (500 - Internal Server
226 Error), but can also be used in other cases.
227
228 See "default_response_codes" in Mojolicious::Plugin::OpenAPI and
229 "default_response_name" in Mojolicious::Plugin::OpenAPI for more
230 details on how to configure these settings.
231
232 The response schema will be added to your spec like this, unless
233 already defined:
234
235 {
236 ...
237 "definitions": {
238 ...
239 "DefaultResponse": {
240 "type": "object",
241 "required": ["errors"],
242 "properties": {
243 "errors": {
244 "type": "array",
245 "items": {
246 "type": "object",
247 "required": ["message"],
248 "properties": {"message": {"type": "string"}, "path": {"type": "string"}}
249 }
250 }
251 }
252 }
253 }
254 }
255
256 The "errors" key will contain one element for all the invalid data, and
257 not just the first one. The useful part for a client is mostly the
258 "path", while the "message" is just to add some human readable debug
259 information for why this request/response failed.
260
261 Rendering binary data
262 Rendering assets and binary data should be accomplished by using the
263 standard Mojolicious tools:
264
265 sub get_image {
266 my $c = shift->openapi->valid_input or return;
267 my $asset = Mojo::Asset::File->new(path => "image.jpeg");
268
269 $c->res->headers->content_type("image/jpeg");
270 $c->reply->asset($asset);
271 }
272
274 Mojolicious::Plugin::OpenAPI, <https://openapis.org/specification>.
275
276
277
278perl v5.34.0 Mojoli2c0i2o2u-s0:1:-P2l1ugin::OpenAPI::Guides::OpenAPIv2(3)