README.md in dry-swagger-0.5.2 vs README.md in dry-swagger-0.6.0
- old
+ new
@@ -13,273 +13,273 @@
And then execute:
bundle install
-Or install it yourself as:
+After installing, execute the following command:
+
+ rake dry-swagger:install
- gem install dry-swagger
+This will generate configuration files in your project under `project/config`. See Configuration section for more details.
-## Usage
-## Dry::Validation::Contract
- class Contract < Dry::Validation::Contract
- json do
- required(:required_field).value(:str?)
- required(:required_nullable_field).maybe(:str?)
- required(:required_filled_field).filled(:str?)
-
- optional(:optional_field).value(:str?)
- optional(:optional_nullable_field).maybe(:str?)
- optional(:optional_filled_field).filled(:str?)
- end
- end
+##Usage
+
+####With Dry::Validation::Contract
+Lets say we have the following Dry::Validation::Contract definition:
- Dry::Swagger::ContractParser.new.call(Contract).to_swagger
- => {
- "type": "object",
- "properties": {
- "required_field": {
- "type": "string",
- "nullable": false
- },
- "required_nullable_field": {
- "type": "string",
- "nullable": true
- },
- "required_filled_field": {
- "type": "string",
- "nullable": false
- },
- "optional_field": {
- "type": "string",
- "nullable": false
- },
- "optional_nullable_field": {
- "type": "string",
- "nullable": true
- },
- "optional_filled_field": {
- "type": "string",
- "nullable": false
- }
- },
- "required": [
- "required_field",
- "required_nullable_field",
- "required_filled_field"
- ]
- }
-#### With nested fields - hash or array
- class Contract < Dry::Validation::Contract
- json do
- required(:array_field).array(:int?)
- required(:array_of_hash).array(:hash) do
- required(:field).value(:str?)
+ 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
- required(:hash_field).hash do
- required(:field).value(:str?)
- end
- end
end
- Dry::Swagger::ContractParser.new.call(Contract).to_swagger
- => {
- "type": "object",
- "properties": {
- "array_field": {
- "type": "array",
- "items": {
- "type": "integer"
- }
- },
- "array_of_hash": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "field": {
- "type": "string",
- "x-nullable": false
- }
- },
- "required": [
- "field"
- ]
- }
- },
- "hash_field": {
- "type": "object",
- "properties": {
- "field": {
- "type": "string",
- "x-nullable": false
- }
- },
- "required": [
- "field"
- ]
- }
- },
- "required": [
- "array_field",
- "array_of_hash",
- "hash_field"
- ]
- }
+ parser = Dry::Swagger::ContractParser.new
-### With Dry::Struct
- class DTO < Dry::Struct
- attribute :required_string, Types::String
- attribute :required_nullable_string, Types::String.optional
- attribute :required_string_with_enum, Types::String.enum('enum1')
- attribute? :optional_string, Types::String
- attribute? :optional_nullable_string, Types::String.optional
- end
+`parser.call(TestContract)` will set the `keys` of the `parser` object to:
- Dry::Swagger::StructParser.new.call(DTO).to_swagger
- => {
- "type": "object",
- "properties": {
- "required_string": {
- "type": "string",
- "x-nullable": false
- },
- "required_nullable_string": {
- "type": "string",
- "x-nullable": true
- },
- "required_string_with_enum": {
- "type": "string",
- "enum": [
- "enum1"
- ],
- "x-nullable": false
- },
- "optional_string": {
- "type": "string",
- "x-nullable": false
- },
- "optional_nullable_string": {
- "type": "string",
- "x-nullable": true
- }
+ {
+ :some_field => {
+ :required => true,
+ :type => "string",
+ :description => "Minimum size: 5, Maximum size: 10"
+ },
+ :some_array_of_objects => {
+ :required => true,
+ :array => true,
+ :type => "array",
+ :keys => {
+ :some_nested_attribute => {
+ :required=>true, :type=>"string"
+ }
+ }
},
- "required": [
- "required_string",
- "required_nullable_string",
- "required_string_with_enum"
- ]
- }
-#### With nested fields
- class NestedDTO < Dry::Struct
- attribute :required_string, Types::String
- attribute :required_nullable_string, Types::String.optional
- attribute :required_string_with_enum, Types::String.enum('enum1')
- attribute? :optional_string, Types::String
- attribute? :optional_nullable_string, Types::String.optional
- end
+ :some_array_of_integers => {
+ :required=>true,
+ :array=>true,
+ :type=>"integer"
+ },
+ :dto => {
+ :required => true,
+ :type => "hash",
+ :keys => {
+ :some_nested_attribute => {
+ :required => false,
+ :"x-nullable"=>true,
+ :type=>"string"
+ }
+ }
+ }
+ }
+
+As we can see, the `ContractParser` goes through all the params defined in the
+schema and generates a hash. The hash is saved in the `keys` attribute of the parser,
+so that we can call `to_swagger` later.
+
+The required key in our result will be set to `true` if the field is defined as
+`required(:field_name)`, and `false` if defined as `optional(:field_name)`.
+
+The "x-nullable" key depends on whether we have defined the field as value, maybe or filled.
+
+For nested objects like array of objects or hash, we add a keys field with a definition
+for each field inside the nested hash.
+
+If the field is an array of primitive type, the type field will equal to the primitive type, and a
+array flag will be set on the field.
+
+Calling `parser.to_swagger` will give the following result:
- class DTO < Dry::Struct
- attribute :array_of_integer, Types::Array.of(Types::Integer)
- attribute :array_of_objects, Types::Array.of(NestedDTO)
- attribute :dto, NestedDTO
- end
-
- Dry::Swagger::StructParser.new.call(DTO).to_swagger
- => {
+ {
"type": "object",
"properties": {
- "array_of_integer": {
- "type": "array",
- "items": {
- "type": "integer"
- },
+ "some_field": {
+ "type": "string",
+ "description": "Minimum size: 5, Maximum size: 10",
"x-nullable": false
},
- "array_of_objects": {
+ "some_array_of_objects": {
"type": "array",
"items": {
"type": "object",
"properties": {
- "required_string": {
+ "some_nested_attribute": {
"type": "string",
"x-nullable": false
- },
- "required_nullable_string": {
- "type": "string",
- "x-nullable": true
- },
- "required_string_with_enum": {
- "type": "string",
- "enum": [
- "enum1"
- ],
- "x-nullable": false
- },
- "optional_string": {
- "type": "string",
- "x-nullable": false
- },
- "optional_nullable_string": {
- "type": "string",
- "x-nullable": true
}
},
"required": [
- "required_string",
- "required_nullable_string",
- "required_string_with_enum"
- ]
+ "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": {
- "required_string": {
+ "some_nested_attribute": {
"type": "string",
- "x-nullable": false
- },
- "required_nullable_string": {
- "type": "string",
"x-nullable": true
- },
- "required_string_with_enum": {
- "type": "string",
- "enum": [
- "enum1"
- ],
- "x-nullable": false
- },
- "optional_string": {
- "type": "string",
- "x-nullable": false
- },
- "optional_nullable_string": {
- "type": "string",
- "x-nullable": true
}
},
"required": [
- "required_string",
- "required_nullable_string",
- "required_string_with_enum"
+
],
"x-nullable": false
}
},
"required": [
- "array_of_integer",
- "array_of_objects",
+ "some_field",
+ "some_array_of_objects",
+ "some_array_of_integers",
"dto"
]
}
-## Overriding fields on run time
-You can also modify the fields during runtime by passing a block after the .call() method.
-For example:
+####With Dry::Struct
+The `Dry::Swagger::StructParser` works the same as the contract parser.
+
+The required key depends on whether we define the field as attribute or attribute?
+
+The "x-nullable" key depends on whether we define the type as Type or Type.optional.
+
+For more complex types, for example DTO1 | DTO2 or Types::Array.of(DTO1 | DTO2),
+the parser converts the field value to an array of both schemas.
+
+Example:
+ 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
+ parser = Dry::Swagger::StructParser.new
+
+ parser.call(DTO)
+ => {
+ "dynamic_dto": [ # ARRAY
+ {
+ "type": "hash",
+ "required": true,
+ "x-nullable": false,
+ "keys": {
+ "dto1_field": {
+ "type": "string",
+ "required": true,
+ "x-nullable": false
+ }
+ }
+ },
+ {
+ "type": "hash",
+ "required": true,
+ "x-nullable": false,
+ "keys": {
+ "dto2_field": {
+ "type": "string",
+ "required": true,
+ "x-nullable": false
+ }
+ }
+ }
+ ]
+ }
+
+Calling `parser.to_swagger` will give the following result:
+
+ {
+ "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
+You can also modify the fields by passing a block after the .call() method.
+
Dry::Swagger::StructParser.new.call(DTO) do |it|
# types = string/integer/hash/array
# Remove a field
its.keys = it.keys.except(:field_name)
@@ -309,29 +309,15 @@
it.keys[:array_field_name] = {
type: type, array: true, required: true/false, :it.config.nullable_type=> true/false
}
end.to_swagger()
-## Custom Configuration For Your Project
-You can override default configurations by creating a file in config/initializers/dry-swagger.rb and changing the following values.
-
- Dry::Swagger::Config::StructConfiguration.configuration do |config|
- config.enable_required_validation = true / false
- config.enable_nullable_validation = true / false
- config.enable_enums = true / false
- config.enable_descriptions = true / false
- config.nullable_type = :"x-nullable" / :nullable
- end
- Dry::Swagger::Config::ContractConfiguration.configuration do |config|
- config.enable_required_validation = true / false
- config.enable_nullable_validation = true / false
- config.enable_enums = true / false
- config.enable_descriptions = true / false
- config.nullable_type = :"x-nullable" / :nullable
- end
-
-By default, all these settings are true, and nullable_type is :"x-nullable".
+##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](https://rubygems.org).