ruby-grape / grape

An opinionated framework for creating REST-like APIs in Ruby.
http://www.ruby-grape.org
MIT License
9.89k stars 1.22k forks source link

Ability to describe multiple success entities #2277

Open Koilanetroc opened 2 years ago

Koilanetroc commented 2 years ago

Sometimes it's necessary to return different entities depending on internal business logic. It would be nice to be able to document all possible success entities. Like with failure method but without status codes.
Something like this:

desc "List of users" do
  success [Entities::Customer, Entities::Client]
  is_array true
end
dblock commented 2 years ago

I dislike APIs that return two different types of things, but it's a matter of preference, so the proposal makes sense. Want to give it a try?

Koilanetroc commented 2 years ago

Yeah, I'd like to try. Will send a pr when it's ready

Koilanetroc commented 2 years ago

Well, after some research I realised that limitation was from OpenAPI 2.0. It does not support multiple response schemas per status code. There is a branch in grape-swagger for oapi-3, but it's abandoned, so there is no way to add this functionality for now.

dblock commented 2 years ago

But is it a grape-swagger problem or a grape problem? Can we do one without the other?

Koilanetroc commented 2 years ago

Grape-swagger actually is able to accept an array in success section, but then in response_object hash is used for storing entities where response code is a key. So if you pass an array of multiple entities with same response codes like this:

  desc 'user' do
    success [{ code: 200, model: Entities::User }, { code: 200, model: Entities::Admin }]
  end

In swagger you'll see only Entities::Admin as a result for 200. If you pass entities with different codes they will appear in swagger correctly. As I said before, there is a limitation from openapi 2.0. It also uses response code as a key:

  "paths": {
    "/user": {
      "get": {
        "description": "user",
        "produces": [
          "application/json"
        ],
        "responses": {
          "200": {
            "description": "user",
            "schema": {
              "$ref": "#/definitions/User"
            }
          }
        },
        "tags": [
          "user"
        ],
        "operationId": "getUser"
      }
    }
  }

And you can't pass an array to "200" key, this option is available only in openapi 3

dblock commented 2 years ago

Looks like a bug in grape-swagger, which should raise an error here, short of supporting openapi 3.

For Grape though I don't see a reason not to implement it. If someone ends up using it and swagger has a problem with it, 🤷