rswag icon indicating copy to clipboard operation
rswag copied to clipboard

Validating schemas on responses

Open braindeaf opened this issue 3 years ago • 1 comments

I've just spent the evening mulling over this one, I was looking at our Swagger documentation and it's Schemas section has a whole bunch of data that should really be hidden from the consumer, mostly because it's unnecessary. Our definitions / schemas have a host of re-usable snippets that have no business being in the final documentation.

Screenshot 2021-08-12 at 09 06 21

So I started tidying up and reading the Swagger documentation.

https://swagger.io/docs/specification/components

It would appear that I can shuffle off many of the reusable snippets into different component sections e.g. parameters, responses, etc. But when it comes to validating them from our spec it won't work.

response '403', 'Error: Forbidden' do
  schema '$ref' => '#/components/responses/error_403'

  context 'when requesting another user' do
    let(:id) { users.second.id }

    run_test!
  end
end

Quite understandably when you define a response schema it queries the 'schemas' section of 'components'

module Rswag
  module Specs
    class ResponseValidator
      private def definitions_or_component_schemas(swagger_doc, version)
        if version.start_with?('2')
          swagger_doc.slice(:definitions)
        else # Openapi3
          if swagger_doc.key?(:definitions)
            ActiveSupport::Deprecation.warn('Rswag::Specs: WARNING: definitions is replaced in OpenAPI3! Rename to components/schemas (in swagger_helper.rb)')
            swagger_doc.slice(:definitions)
          else
            components = swagger_doc[:components] || {}
            { components: { schemas: components[:schemas] } }
          end
        end
      end
    end
  end
end

But I need to organise my code such that I can test the response against our snippets and schemas. This hacks it for my purposes but I wonder what the opinion on a better approach is?

module Rswag
  module Specs
    class ResponseValidator
      private def definitions_or_component_schemas(swagger_doc, version)
        if version.start_with?('2')
          swagger_doc.slice(:definitions)
        else # Openapi3
          if swagger_doc.key?(:definitions)
            ActiveSupport::Deprecation.warn('Rswag::Specs: WARNING: definitions is replaced in OpenAPI3! Rename to components/schemas (in swagger_helper.rb)')
            swagger_doc.slice(:definitions)
          else
            components = swagger_doc[:components] || {}
            # { components: { schemas: components[:schemas] } }
            { components: components }
          end
        end
      end
    end
  end
end

Happy to contribute a fix / solution on this.

braindeaf avatar Aug 12 '21 08:08 braindeaf

I think allowing the different components would be super useful. I've noticed the same behavior but didn't realize there were different component types until I read the link you shared

We end up creating snippets for things that we'd like to re-use but they really don't make sense to show as schema definitions. Happy to code review, pair, or share ideas on this as well.

jaydorsey avatar Aug 14 '21 01:08 jaydorsey

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If the issue is still relevant to you, please leave a comment stating so to keep the issue from being closed. Thank you for your contributions.

stale[bot] avatar Aug 14 '22 06:08 stale[bot]