Perl Mojolicious persistent validation error "Properties not allowed: components, openapi, servers"

369 Views Asked by At

I'm looking at creating an api using OpenAPI V3 in Perl with Mojolicious. Both OpenAPI and Mojolicious are new to me.

Mojolicious::Plugin::OpenAPI looks to be under active development with the the latest version 3.31 being released less than a day ago as of writing this.

I have a test demo i am working on and have overcome allot of problems but i am completely stuck on this error as it makes no sense saying properties in my open api spec are not allowed despite being within the openapi spec.

**EDIT - Here is a bare minimum example which works using OpenAPI V2 but if i convert the yaml file into V3 spec the error occurs. Both yaml files pass checks on https://editor.swagger.io/

App2_0.pm

package App2_0;
use Mojo::Base "Mojolicious";

sub startup {
  my $self = shift;
  $self->plugin("OpenAPI" => {url => $self->home->rel_file("api.yaml")});
}
1;

Echo.pm

package App2_0::Controller::Echo;
use Mojo::Base "Mojolicious::Controller";  
sub index {
  # Render back the same data you received
  $self->render(openapi => $self->req->json);
}   
1;

basic.t

use Mojo::Base -strict;

use Test::More;
use Test::Mojo;

my $t = Test::Mojo->new('App2_0');
$t->post_ok('/api/echo', '{"i":"work"}')->status_is(200)->json_is({i=>"work"});

done_testing();

api.yaml

swagger: '2.0'
info:
  version: '1.0'
  title: An API
basePath: "/api"
paths:
  "/echo":
    post:
      x-mojo-to: "echo#index"
      operationId: echo
      parameters:
      - in: body
        name: body
        schema:
          type: object
      responses:
        200:
          description: Echo response
          schema:
            type: object

api.yaml (same as above but in V3)

openapi: 3.0.2
info:
  version: '1.0'
  title: An API
servers:
  - url: "/api"
paths:
  "/echo":
    post:
      x-mojo-to: "echo#index"
      operationId: echo
      requestBody:
        content:
          application/json:
            schema:
              type: object
      responses:
        '200':
          description: ech response
          content:
            application/json:
              schema:
                type: object

Running test with V2 yaml works

prove -l t
t/basic.t .. ok
All tests successful.
Result: PASS

The same test but using the V3 yaml fails

prove -l t
    Invalid JSON specification HASH(0x4415710):
- /: Properties not allowed: openapi, servers. at /usr/local/share/perl5/JSON/Validator.pm line 159.

...

t/basic.t .. Dubious, test returned 255 (wstat 65280, 0xff00)
No subtests run

Test Summary Report
-------------------
t/basic.t (Wstat: 65280 Tests: 0 Failed: 0)
  Non-zero exit status: 255
  Parse errors: No plan found in TAP output
Result: FAIL

**END EDIT the rest is just my OP example which is now redundant

Invalid JSON specification HASH(0x3801f58): - /: Properties not allowed: components, openapi, 
servers. at /usr/local/share/perl5/JSON/Validator.pm line 159.

This is my test demo openapi spec

myapi_y2.yaml

openapi: 3.0.2
info:
  version: '1.0'
  title: An API
servers:
  - url: "/api"
paths:
  "/pets":
    get:
      operationId: get_pets
      x-mojo-name: get_pets
      x-mojo-to: pet#list
      summary: Finds pets in the system
      parameters:
        - in: query
          name: age
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              type: object
      responses:
        '200':
          description: Pet response
          content:
            application/json:
              schema:
                type: object
                properties:
                  pets:
                    type: array
                    items:
                      type: object                 
components:
  schemas:
    Pet:
      type: object
      required:
        - id
        - name
        - age
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
        age:
          type: integer
          format: int64
    Pets:
      type: array
      items:
        $ref: "#/components/schemas/Pet"
    Error:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: integer
          format: int32
        message:
          type: string                  

I have exhausted google and cannot find any info on why this is happening. Has anyone seen this or know why it happens?

Test demo code my_app2

#!/usr/bin/env perl

use strict;
use warnings;

use FindBin;
BEGIN { unshift @INC, "$FindBin::Bin/../lib" }
use Mojolicious::Commands;

# Start command line interface for application
Mojolicious::Commands->start_app('MyApp2');

MyApp2.pm

package MyApp2;
use Mojo::Base "Mojolicious";

sub startup {
  my $app = shift;
  $app->plugin("OpenAPI" => {url => $app->home->rel_file("myapi_y2.yaml"), schema => 'v3'});
}

1;

Pet.pm

package MyApp2::Controller::Pet;
use Mojo::Base "Mojolicious::Controller";

sub list {

  my $c = shift->openapi->valid_input or return;

  my $age  = $c->param("age");
  my $body = $c->req->json;

  # $output will be validated by the OpenAPI spec before rendered
  my $output = {pets => [{name => "kit-e-cat"}]};
  $c->render(openapi => $output);
}

1;

Thanks

0

There are 0 best solutions below