Giter Site home page Giter Site logo

jane-terziev / dry-swagger Goto Github PK

View Code? Open in Web Editor NEW
29.0 2.0 3.0 68 KB

Generate swagger documentation out of Dry::Struct and Dry::Validation::Contract schemas.

Home Page: https://jane-terziev.github.io/dry-swagger/

License: MIT License

Ruby 99.77% Shell 0.23%
rswag dry-rb dry-struct dry-validation swagger rubygem ruby-gem

dry-swagger's Introduction

Dry::Swagger

Generate a valid and up to date swagger documentation out of your dry-structs and dry-validations

The gem is still work in progress and is not yet fully tested.

IMPORTANT:

If you are upgrading from version 1 to version 2, you will need to replace:

Dry::Swagger::StructParser.new.call(struct)

with

Dry::Swagger::DocumentationGenerator.new.from_struct(struct) 

and replace

Dry::Swagger::ContractParser.new.call(contract)

with

Dry::Swagger::DocumentationGenerator.new.from_validation(contract).

For the configuration file in project/config/initializers/dry-swagger.rb, you will need to replace:

Dry::Swagger::Config::ContractConfiguration -> Dry::Swagger::Config::SwaggerConfiguration

you do not need both ContractConfiguration and StructConfiguration.

Installation

Add this line to your application's Gemfile:

gem 'dry-swagger'

And then execute:

bundle install

After installing, execute the following command:

rake dry-swagger:install

This will generate configuration files in your project under project/config. See Configuration section for more details.

Usage

With Dry::Validation::Contract

class TestContract < Dry::Validation::Contract
    params do
        required(:some_field).value(:str?, min_size?: 5, max_size?: 10)
        required(:some_array_of_objects).array(:hash) do
            required(:some_nested_attribute).value(:str?)
        end
        required(:some_array_of_integers).array(:int?)
        required(:dto).value(:hash) do
            optional(:some_nested_attribute).maybe(:str?)
        end
    end
end

Dry::Swagger::DocumentationGenerator.new.from_validation(TestContract)
=> {
      "type": "object",
      "properties": {
        "some_field": {
          "type": "string",
          "description": "Minimum size: 5, Maximum size: 10",
          "x-nullable": false
        },
        "some_array_of_objects": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "some_nested_attribute": {
                "type": "string",
                "x-nullable": false
              }
            },
            "required": [
              "some_nested_attribute"
            ],
            "x-nullable": false
          },
          "x-nullable": false
        },
        "some_array_of_integers": {
          "type": "array",
          "items": {
            "type": "integer",
            "x-nullable": false
          },
          "x-nullable": false
        },
        "dto": {
          "type": "object",
          "properties": {
            "some_nested_attribute": {
              "type": "string",
              "x-nullable": true
            }
          },
          "required": [
    
          ],
          "x-nullable": false
        }
      },
      "required": [
        "some_field",
        "some_array_of_objects",
        "some_array_of_integers",
        "dto"
      ]
    }

With Dry::Struct

class DTO1 < Dry::Struct
    attribute :dto1_field, Types::String
end

class DTO2 < Dry::Struct
    attribute :dto2_field, Types::String
end

class DTO < Dry::Struct
    attribute :dynamic_dto, DTO1 | DTO2
end

Dry::Swagger::DocumentationGenerator.new.from_struct(DTO)
=> {
      "type": "object",
      "properties": {
        "dynamic_dto": {
          "type": "object",
          "properties": {
            "definition_1": {
              "type": "object",
              "properties": {
                "dto1_field": {
                  "type": "string",
                  "x-nullable": false
                }
              },
              "required": [
                "dto1_field"
              ],
              "x-nullable": false
            },
            "definition_2": {
              "type": "object",
              "properties": {
                "dto2_field": {
                  "type": "string",
                  "x-nullable": false
                }
              },
              "required": [
                "dto2_field"
              ],
              "x-nullable": false
            }
          },
          "example": "Dynamic Field. See Model Definitions",
          "oneOf": [
            {
              "type": "object",
              "properties": {
                "dto1_field": {
                  "type": "string",
                  "x-nullable": false
                }
              },
              "required": [
                "dto1_field"
              ],
              "x-nullable": false
            },
            {
              "type": "object",
              "properties": {
                "dto2_field": {
                  "type": "string",
                  "x-nullable": false
                }
              },
              "required": [
                "dto2_field"
              ],
              "x-nullable": false
            }
          ]
        }
      },
      "required": [
        "dynamic_dto"
      ]
    }

Overriding fields

The documentation generator returns the result as a hash, so you can easily modify it based on your needs.

Custom Configuration For Your Project

You can override default configurations by changing the values in the config/initializers/dry-swagger.rb file generated from the rake command in the Installation section.

To modify the descriptions for the Contracts, modify the values in config/locale/dry-swagger.yml.

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/Jane-Terziev/dry-swagger. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

License

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the Dry::Swagger project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

dry-swagger's People

Contributors

jane-terziev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

dry-swagger's Issues

Dry uuid_v4 support?

First, thanks for this awesome gem. :)

I'm encountering a small issue. I have a contract like this:

class Contracts::IndexContract < Dry::Validation::Contract
  params do
    optional(:filter).hash do
      optional(:farm_id).filled(:uuid_v4?)
    end
  end
end

Sadly when I call Dry::Swagger::DocumentationGenerator.new.from_validation on it, I get:

StandardError: Could not generate documentation for field farm_id. The field is missing a type.
          If the field you have defined is an array, you must specify the type of the elements in that array.
          Valid types are: ["string", "integer", "boolean", "float", "decimal", "datetime", "date", "time"].
          The parser has generated the following definition for the field: farm_id: {:required=>false}.

How can I make that work? I would be fine with having string as type in that scenario.

I'm on dry-swagger-2.0.3.

Support AnyValue?

In my contract sometimes I need to support "AnyObject" basically, as I don't know necessarily the format of what will be given to me beforehand. I just want to store what I'm being given.

So I have this:

class Contracts::Sensors::NewContract < Dry::Validation::Contract
  params do
    required(:name).filled(:string)
    optional(:metadata).hash
  end

  def to_swagger
    Dry::Swagger::DocumentationGenerator.new.from_validation(self.class)
  end
end

Sadly if I call Contracts::Sensors::NewContract.new.to_swagger

I get:

StandardError: Could not generate documentation for field metadata. The field is defined as hash,
          but the schema is not defined.
          Valid types are: ["string", "integer", "boolean", "float", "decimal", "datetime", "date", "time", "uuid"].
          The parser has generated the following definition for the field: metadata: {:required=>false, :type=>"hash"}
          
from /nix/store/7hz0irlib58xlr2m40kb076hw24lnp6j-ruby3.2-dry-swagger-2.0.4/lib/ruby/gems/3.2.0/gems/dry-swagger-2.0.4/lib/dry/swagger/documentation_generator.rb:41:in `rescue in block in generate_documentation'
Caused by Dry::Swagger::Errors::MissingHashSchemaError: Dry::Swagger::Errors::MissingHashSchemaError
from /nix/store/7hz0irlib58xlr2m40kb076hw24lnp6j-ruby3.2-dry-swagger-2.0.4/lib/ruby/gems/3.2.0/gems/dry-swagger-2.0.4/lib/dry/swagger/documentation_generator.rb:99:in `generate_for_hash'

I wonder if there is a way this could support some sort of AnyValue?
From my understanding, it's possible in openapi 3 to do:

# openapi: 3.0.0
components:
  schemas:
    AnyValue: {}

And then use that.
Is there maybe a way to support custom schemas in dry-swagger? Or am I using it wrong?

Namespace config raises error

Hi guys,

Not sure if this is something on your side, or on another Dry gem, but hope you could guide me to the proper repo to describe them the issue.

I have the following Contract:

class ApplicationContract < Dry::Validation::Contract
  config.messages.backend = :i18n
end

  class ResourceContract < ApplicationContract
config.messages.namespace = 'parcels.create'

...some json schema specs...
end

When running Dry::Swagger::DocumentationGenerator.new.from_validation(ResourceContract)

I get the error:

/home_path/.rvm/gems/ruby-3.2.2/gems/dry_validation_parser-0.1.11/lib/dry_validation_parser/validation_schema_parser.rb:58:in `public_send': undefined method `visit_namespace' for #<DryValidationParser::ValidationSchemaParser:0x00007e4380b005d0 @keys={}> (NoMethodError)                                                                                     
                                                                                                                                                    
      public_send(:"visit_#{meth}", rest, opts)                                                                                                     
      ^^^^^^^^^^^                                                                                                                                   
Did you mean?  visit_each     

Commenting out the namespace configuration makes the Sweagger DocumentationGenerater run without issues and I get the schema as a Hash.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.