khrt / Raisin

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

"using" in an entity without declaring an OpenAPI array #46

Open davel opened 5 years ago

davel commented 5 years ago

Hello,

I am trying to use Raisin for an API which returns a single row of data, read by calling DBIx::Class's ->find(). I am having trouble making the generated OpenAPI / Swagger schema agree with the generated JSON.

I have two Raisin::Entity classes. One represents the row from DBIx::Class. The other represents the JSON data presented by an endpoint. It refers to the first via expose 'data', using => .... When the Swagger schema is generated, it declared the data is an array, when it is in fact an object represented by a hash.

Is there a way to make Raisin generate a schema matching the returned data?

Many thanks, Dave

khrt commented 5 years ago

Hi,

that happens, because DBIx::Class's ->find() returns DBIx::Class::ResultSet as result.

If you could provide me with sample data and application maybe I might help then.

Thanks.

davel commented 5 years ago

The problem is that swagger.json does not agree with the generated output. For example in the music app, swagger.json claims that /artists returns data described by,

               "200" : {
                  "description" : "List",
                  "schema" : {
                     "$ref" : "#/definitions/MusicApp::Entity::Artist-302668EB84"
                  }
               },

However, MusicApp::Entity::Artist is not what is returned. Instead, we get a hash with elements count and data.

 `{"count":2,"data":[{"hash":"10","artist":"Nirvana", ...

You can fix this when an array is returned, eg. https://github.com/davel/Raisin/commit/bb5fb43c373dba7eafacf7c41bca000a9fbde623

.... but you cannot fix this where a single object is returned, such as with the /artists{id} endpoint. This change, https://github.com/davel/Raisin/commit/c4f9edad35ee891f7ab4a87728f3e7fa3bd63524

Causes data to be described as an array, which is incorrect.

Is there some way I can get the generated swagger to agree with the returned data for the /artists/{id} endpoint?

khrt commented 5 years ago

From what I understand now, it is not possible to reach the agreement between Swagger and the presenter.

As a solution to that we can introduce an argument to Entitie's expose to say the field is HASH or ARRAY.

What do you think?

davel commented 5 years ago

That would make sense to me. Also potentially useful for representing a has_one relationship from DBix::Class.