Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

mojolicious plugin openapi_tutorial

jonasbn edited this pageJul 26, 2018 ·10 revisions

Tutorial on Mojolicious::Plugin::OpenAPI

I have always wanted to get my handsdirty withSwagger. I recently fell overMojolicious::Plugin::OpenAPI, which fits into myboring stack and I decided to do a prototype.

I followed thetutorial for Mojolicious::Plugin::OpenAPI and found it a bit confusing, so I decided to write up a more simple tutorial.

This tutorial requires that you haveMojolicious installed and recommendscarton. The installation of these components is however beyond the scope of this tutorial.

OpenAPI comes fromSwagger, which I have had a look at, much water has run under that bridge, so now it is time to look atOpenAPI a specification on how to write RESTful APIs in a standardised format.

Here goes, lets start with a basichello world example,all files are available on GitHub.

Hello World

First we set up an application, yes we could do aMojolicious lite-app, but I primarily useMojolicious apps, so I think it makes sense to keep stick to this for reference.

$ mojo generate app HelloWorld

Jump into our newly generated application directory

$cd hello_world

We then install the plugin we need to enableOpenAPI in ourMojolicious application

UsingCPAN shell:

$ perl -MCPAN -e shell install Mojolicious::Plugin::OpenAPI

Usingcpanm:

$ cpanm Mojolicious::Plugin::OpenAPI

If you need help installing please refer tothe CPAN installation guide.

Create a definition JSON file based onOpenAPI to support an Hello World implementation based on theOpenAPI specification:

$ touch openapi.conf

The exact name of this file is insignifcant, I just prefer to have clear and understandable filenames for easy identification.

Openopenapi.conf and insert the followingsnippet:

{"swagger":"2.0","info": {"version":"1.0","title":"Hello World example" },"basePath":"/api","paths": {"/hello_world": {"get": {"operationId":"helloWorld","x-mojo-name":"hello_world","x-mojo-to":"example#hello_world","summary":"Example app returning hello world","responses": {"200": {"description":"Returning string 'hello world'","schema": {"type":"object","properties": {"greeting": {"type":"string"                    }                }              }            },"default": {"description":"Unexpected error","schema": {}            }          }        }      }    }}

Now lets go over our definiton.

  • basePath: defines the root of our URL, so we would be able to access our application at/api, recommendations on versioning APIs using this part is do exist, but for our example application, this is out of scope.

  • paths: here we define our first API path, so our Hello World application can be accessed at:/api/hello_world

  • operationId: the is an operation identifier, it is important for the OpenAPI part, whereas the two following definitions are mappings of the same operation identifier towards theMojolicious application

  • x-mojo-name: this is the name used to identify our operation in theMojolicious application

  • x-mojo-to: this is the specification for the route to be used for our operation in theMojolicious application, more on this later

  • responses: here we define the type we want to handle, for now we settle for200. The response definition outline our response, this could be boiled down to astring instead of anobject, with properties, but the example would be cometoo simple and in my opinion we work primarily with objects over basic types, so this extended example makes for a better reference.

Next step is to enable theMetaCPAN: Mojolicious::Plugin::OpenAPI plugin in the application

Open the file:lib/HelloWorld.pm and add the following snippet:

$self->plugin("OpenAPI"=> {url=>$self->home->rel_file("openapi.json")});

Note the pointer to our previously created file:openapi.json.

The complete file should look like the following:

packageHelloWorld;use Mojo::Base'Mojolicious';# This method will run once at server startsubstartup {my$self =shift;$self->plugin('OpenAPI'=> {url=>$self->home->rel_file('openapi.json')});# Load configuration from hash returned by "my_app.conf"my$config =$self->plugin('Config');# Documentation browser under "/perldoc"$self->plugin('PODRenderer')if$config->{perldoc};# Routermy$r =$self->routes;# Normal route to controller$r->get('/')->to('example#welcome');}1;

Then we add the acual operation, open the file:lib/HelloWorld/Controller/Example.pm and add the following snippet:

subhello_world {my$c =shift->openapi->valid_inputorreturn;my$output = {greeting=>'Hello World' };$c->render(openapi=>$output);}

Note that this maps to the definition in our API definition:openapi.conf

"x-mojo-to":"example#hello_world",

The complete file should look like the following:

packageHelloWorld::Controller::Example;use Mojo::Base'Mojolicious::Controller';# This action will render a templatesubwelcome {my$self =shift;# Render template "example/welcome.html.ep" with message$self->render(msg=>'Welcome to the Mojolicious real-time web framework!');}subhello_world {my$c =shift->openapi->valid_inputorreturn;my$output = {greeting=>'Hello World' };$c->render(openapi=>$output);}1;

I decided to implement the tutorial in a scaffolded application, you could create your own controller, but changing an existing controller this way demonstrates how our newly added OpenAPI API end-point, can live in unison with existing and additional end-points.

Now start the application

$ morbo script/hello_world

And finally - lets call the API

$ http http://localhost:3000/api/hello_world

We should now get the result

HTTP/1.1 200 OKContent-Length: 26Content-Type: application/json;charset=UTF-8Date: Thu, 26 Jul 2018 08:20:59 GMTServer: Mojolicious (Perl){"greeting":"Hello World"}

Yay! and our firstMojoliciousOpenAPI implementation works!

In addition to the operation, you can obtain the specification by calling the following URL:/api

$ http http://localhost:3000/api/

And as mentioned earlier our existing operations and parts of the application still works as expected, try calling the URL:/

$ http http://localhost:3000/

That is it for now, good luck with experimenting withMojoliciousOpenAPI integration andOpenAPI. Thanks to Jan Henning Thorsen (@jhthorsen) for the implementation of Mojolicious::Plugin::OpenAPI.

References

Today I Learned/TIL

This wiki is primarily for my notes and stuff, please visitmy page if you want to get in touch

Clone this wiki locally

[8]ページ先頭

©2009-2025 Movatter.jp