khrt / Raisin

Raisin - a REST API micro framework for Perl 🐫 🐪
61 stars 31 forks source link

Round trip: Raisin -> Swagger -> codegen Perl Client #49

Open beccon4 opened 6 years ago

beccon4 commented 6 years ago

Using the samples at Github I set up a rather simple server:

use HTTP::Status qw(:constants);
use List::Util qw(max);
use Raisin::API;
use Types::Standard qw(HashRef Any Int Str);

plugin 'Logger', fallback => 1;
app->log(debug => 'Starting Raisin...');

middleware 'CrossOrigin',
    origins => '*',
    methods => [qw/DELETE GET HEAD OPTIONS PATCH POST PUT/],
    headers => [qw/accept authorization content-type api_key_token/];

plugin 'Swagger';

swagger_setup(
    title       => 'A simple test',
    description => 'Roundtrip Raisin - Swagger - Perl Client',

);

desc 'Users API';
resource foo => sub {
    summary 'foo';
    params(
        requires('foo' , type=> Str ),
    );
    post sub {
        my $params = shift;
        app->log(debug => params->{foo});
        res->status(HTTP_CREATED);
        { success => 1 }
    }

};

run;

Which results in the following Swagger-File:

{
   "security" : [],
   "schemes" : [
      "http"
   ],
   "host" : "localhost:5000",
   "info" : {
      "description" : "Roundtrip Raisin - Swagger - Perl Client",
      "version" : "0.0.1",
      "title" : "A simple test"
   },
   "securityDefinitions" : {},
   "basePath" : "/",
   "definitions" : {},
   "swagger" : "2.0",
   "consumes" : [
      "application/x-yaml",
      "application/json"
   ],
   "tags" : [
      {
         "name" : "foo",
         "description" : "Users API"
      }
   ],
   "paths" : {
      "/foo" : {
         "post" : {
            "consumes" : [
               "application/x-yaml",
               "application/json"
            ],
            "tags" : [
               "foo"
            ],
            "produces" : [
               "application/x-yaml",
               "application/json"
            ],
            "summary" : "foo",
            "responses" : {
               "default" : {
                  "description" : "Unexpected error"
               }
            },
            "operationId" : "post_foo",
            "description" : "",
            "parameters" : [
               {
                  "in" : "formData",
                  "description" : "",
                  "name" : "foo",
                  "type" : "string",
                  "required" : true
               }
            ]
         }
      }
   },
   "produces" : [
      "application/x-yaml",
      "application/json"
   ]
}

Pasting this into the Swagger editor results in the following error message:

Semantic error at paths./foo.post Operations with Parameters of "in: formData" must include "application/x-www-form-urlencoded" or "multipart/form-data" in their "consumes" property

... and the suggested App call:

curl -X POST "http://localhost:5000/foo" -H "accept: application/json" -H "Content-Type: application/json" -d "foo=bar" which is of course not valid as we'd expect something JSON we could pick up from POST, such as curl -X POST "http://localhost:5000/foo" -H "accept: application/json" -H "Content-Type: application/json" -d '{"foo":"bar"}'

The code generated with codegen doen't work either as the server expects formData. The documentation suggests parameter settings as I put in my sample.

Using the full code listing from the Github synposis (user management sample) doesn't result in usable code either.

What's wrong here? An issue with the software or with the documentation?

khrt commented 6 years ago

The part of the code responsible for consume is obviously behind of what Swagger is requiring now.

beccon4 commented 6 years ago

There is a line

"swagger" : "2.0",

which should tell the editor to stick to that version. Or is it something else?

Is there a workaround to produce valid code anyway?

khrt commented 6 years ago

There is no workaround I can guess now, but it shouldn't be hard to fix it. I'll try to come up with solution tonight.

So to clarify a bit the only thing to reproduce the bug is to go to https://editor.swagger.io/ and paste the markup Raisin produces, is that correct?

beccon4 commented 6 years ago

Yes I did so. I also installed the swagger-codegen batch program which produces exact the same result. (it seems to be the same software in both the edior and in the standalone version)