jhthorsen / mojolicious-plugin-openapi

OpenAPI / Swagger plugin for Mojolicious

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

RFE: Document interaction with routes

jszinger opened this issue · comments

The synopsis has the following code snippet:

post "/echo" => sub {
  my $c = shift->openapi->valid_input or return;
  my $data = {body => $c->req->json};
  $c->render(openapi => $data);
}, "echo";

plugin OpenAPI => {url => "data:///spec.json", schema => "v2"};

It works. Loading the plugin first doesn't work:

plugin OpenAPI => {url => "data:///spec.json", schema => "v2"};

post "/echo" => sub {
  my $c = shift->openapi->valid_input or return;
  my $data = {body => $c->req->json};
  $c->render(openapi => $data);
}, "echo";

I spent quite a bit of time trying to find the difference, and didn't find any documentation about this feature.

Now that I know about it the closest thing I see is in the Route Names section of Mojolicious::Plugin::OpenAPI::Guides::OpenAPIv3. "The route name can also be used the other way around, to find already defined routes. This is especially useful for Mojolicious::Lite apps." It is not obvious how it is useful. By searching the source, I think I found the implementation in Mojolicious::Plugin::OpenAPI::_add_routes.

The rules seem to be:

  1. Create a route with an arbitrary path and the desired name matching "x-mojo-name" or "operationId".

  2. Create paths in OpenAPI using "x-mojo-name" or "operationId" to match the route name. (I don't see any advantage to x-mojo-name.) Don't use "x-mojo-to".

  3. Load Mojolicious::Plugin::OpenAPI. It will automatically grab existing routes with matching names. Routes defined later are not affected.

  4. It works just as well in full as in Lite apps.

Please add a description of this feature to the docs.

I'll look into it, but I highly suggest using M::P::OpenAPI with a full (not lite) app. I think that's much easier to work with.

I am building a full app. For the full app the example MyApp::startup looks like

sub startup ($app) {
    my $r = $app->routes;
    # MyApp::Controller::Main::echo has the OpenAPI controller
    $r->get( '/echo')->to( 'main#echo')->name( 'echo');

    $app->plugin( 'Mojolicious::Plugin::OpenAPI' => {url => "data:///spec.json", schema => "v2"});
}

I am intrigued by the syntax in the synopsis, especially the ability to write an OpenAPI spec without any 'x-mojo' content—this avoids exposing implementation details to the API consumers. So I went ahead and tried it and finally figured out the rules I describe above. I'm hoping to help others avoid this suffering.

I also believe that it is important to clearly and fully explain the features used in the SYNOPSIS.

this avoids exposing implementation details to the API consumers
Many people have said this before you, but I don't share your concern. If you do find an alternative way, then please do let me know though.