jhthorsen / mojolicious-plugin-openapi

OpenAPI / Swagger plugin for Mojolicious
54 stars 42 forks source link

SpecRenderer introducing basePath #200

Closed pplu closed 3 years ago

pplu commented 3 years ago

Hi,

With this example server:

#!/usr/bin/env perl

use strict;
use warnings;

use Mojolicious::Lite -signatures;

plugin "Mojolicious::Plugin::OpenAPI::SpecRenderer";

my $json = {
  openapi => "3.0.2",
  info => { version => "0.8", title => "Echo Service" },
  servers => [ { url => "/api" } ],
  paths => {
    "/echo" => {
      post => {
        "x-mojo-name" => "echo",
        requestBody => {
          content => {
            'application/json' => {
              schema => { type => 'object' },
            }
          }
        },
        responses => {
          "200" => {
            description => 'Echo response',
            content => {
              "*/*" => {
                schema => { type => 'object' }
              }
            }
          }
        },
      }
    }
  }
};

get "/api.json" => sub {
  my $c    = shift;
  my $path = $c->param('path') || '/';
  state $custom_spec = JSON::Validator->new->schema($json)->bundle;  
  $c->render(json => $custom_spec);
};

# Load specification and start web server
# The plugin must be loaded *after* defining the routes in a Lite app
plugin OpenAPI => {spec => $json, schema => "v3"};
app->start;

And this sample client:

#!/usr/bin/env perl

use OpenAPI::Client;

my $client = OpenAPI::Client->new("http://localhost:3000/api.json", { schema => 'v3' });

use Data::Dumper;
print Dumper($client);

OpenAPI::Client will die with:

Invalid schema: http://localhost:3000/api.json has the following errors:
/: Properties not allowed: basePath. at /home/pplu/biteright/api-test/local/lib/perl5/OpenAPI/Client.pm line 67.

I can work around the issue by adding:

get "/api.json" => sub {
  my $c    = shift;
  my $path = $c->param('path') || '/';
  state $custom_spec = JSON::Validator->new->schema($json)->bundle;
  delete $custom_spec->{basePath};
  $c->render(json => $custom_spec);
};
jhthorsen commented 3 years ago

Which version of JSON::Validator, OpenAPI::Client and Mojolicious::Plugin::OpenAPI do you have? Not quite sure what's going on, but I have some other (generic) comments to the code:

christopherraa commented 3 years ago

Might it be that this is the same issue which I have detailed in #199 ?

pplu commented 3 years ago

Which version of JSON::Validator, OpenAPI::Client and Mojolicious::Plugin::OpenAPI do you have?

carton installed from today

  • Why do you have plugin "Mojolicious::Plugin::OpenAPI::SpecRenderer";? It does not seem like you use it.

OK, I see what happened here: I got the "get api.json" controller from the documentation, but it wasn't working for me because i had:

my $json = {
  ...
};

get "/api.json" => sub {
  ...
};

plugin OpenAPI => {spec => $json, schema => "v3"};

The api.json endpoint was returning an empty openapi definition, so It seems I got the thing to work via a plain old render (this was done some weeks ago when I was trying to use OpenAPI::Client, and I realized it didn't have support for v3, so it was a detail I didn't remember even doing).

Everything is working now by changing the "get api.json" method below the plugin load:

my $json = {
  ...
};

plugin OpenAPI => {spec => $json, schema => "v3"};

get "/api.json" => sub {

};

I've been able to invoke the renderspec method again, and all is working. No need to do any mangling, since https://github.com/jhthorsen/mojolicious-plugin-openapi/blob/master/lib/Mojolicious/Plugin/OpenAPI/SpecRenderer.pm#L141 already deletes that stray basePath...

  • There's no need to specify schema => "v3" anymore when loading the OpenAPI plugin

Thanks! I wasn't aware

  • OpenAPI::Client does not have a "schema" attribute

Thanks again! That was code added while trying to diagnose what was happening!

On my side, I solved the issue, but I bumped into that strangeness of the basePath being there by accident.