Coder Social home page Coder Social logo

json-schema_builder's People

Contributors

jirutka avatar parrish 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

Watchers

 avatar  avatar

json-schema_builder's Issues

Add #format= to JSON::SchemaBuilder::String

The spec allows one to declare

{
  "links": {
    "description": "A resource object **MAY** contain references to other resource objects (\"relationships\"). Relationships may be to-one or to-many. Relationships can be specified by including a member in a resource's links object.",
    "type": "object",
    "properties": {
      "self": {
        "description": "A `self` member, whose value is a URL for the relationship itself (a \"relationship URL\"). This URL allows the client to directly manipulate the relationship. For example, it would allow a client to remove an `author` from an `article` without deleting the people resource itself.",
        "type": "string",
        "format": "uri"
      },
      "related": {
        "$ref": "#/definitions/link"
      }
    },
    "additionalProperties": true
  }
}

is there a way to compose a schema out of multiple smaller schemas?

Hey!

I'm trying to split up the rather clunky schema for JSONAPI into parts and combine them per use case.

It seems possible to assign a nested object definition as items to any array.
But when i try to add an object to another object with a name it's properties stay empty

{"type"=>:object, "properties"=>{"data"=>{"type"=>"object", "properties"=>{}}}}

Is there a way or would i have to add something like a properties method to object that behave like items on array ?

Thanks,
Ralf

Usage of "pattern_properties" with object

In JSON Schema, it is possible to define object properties based on regular expressions, even while still using fixed keys:

{
  "type": "object",
  "properties": {
    "builtin": { "type": "number" }
  },
  "patternProperties": {
    "^S_": { "type": "string" },
    "^I_": { "type": "integer" }
  }
}

Looking into the object class, I tried to translate this to your DSL as follows:

class MySchema
  require 'json/schema_builder'
  include JSON::SchemaBuilder

  def schema
    object do
      pattern_properties do
        string '^S_'
        string '^I_'
      end

      number :builtin
    end
  end
end

puts JSON.pretty_generate(MySchema.new.schema.as_json)

This only leads to everything outside pattern_properties to be generated:

{
  "type": "object",
  "properties": {
    "builtin": {
      "type": "number"
    }
  }
}

My next try was to specify the pattern properties as option for object, but this only lead to patternProperties without the actual patterns:

object pattern_properties: [string('^S_')] do
   ...
end
{
  "type": "object",
  "patternProperties": [
    {
      "type": "string"
    }
  ],
  "properties": {
    "builtin": {
      "type": "number"
    }
  }
}

Could you give me an example of how to correctly use pattern arguments in your DSL?
Thanks in advance!

Allow for builder-style DSL

First, great gem!

It would be nice though to be able to pass Instances of Builders ( for example JSON::SchemaBuilder::Object) around and build them up from the outside. Example:

def post(obj)
  obj.string :title
  obj.string :body
end

obj = JSON::SchemaBuilder::Object.new
post(obj)

This way you could keep your definition logic in POROs (which some prefer).
I realize this is already somewhat possible, but the Builders Schema is only updated on initialization (as far as I can see).
So simply updating at each entity call could be enough.

Usage of any_of with array items

Hey! First of all, thank you for providing a (currently: the) DSL to generate JSON schemas in Ruby!

I solved this problem by now (see below), but I'll include my original issue message here anyway as it might make for a good addition to the examples


I ran into a problem today when describing a rather complex schema that included an array of polymorphic objects.

From my understanding of JSON schema, it should be possible to simply define "items" using the "anyOf" keyword and then specifying the various objects which might occur as array items. I built a small example:

class MySchema
  require 'json/schema_builder'
  include JSON::SchemaBuilder

  def schema
    object do
      array :an_array do
        items do
          any_of [
            object { string(:name) },
            object { number(:age) }
          ]
        end
      end
    end
  end
end

puts JSON.pretty_generate(MySchema.new.schema.as_json)

This indeed generates a corresponding anyOf, but it also adds a type and properties to items:

{
  "type": "object",
  "properties": {
    "an_array": {
      "type": "array",
      "items": {
        "anyOf": [
          {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              }
            }
          },
          {
            "type": "object",
            "properties": {
              "age": {
                "type": "number"
              }
            }
          }
        ],
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "age": {
            "type": "number"
          }
        }
      }
    }
  }
}

I also tried to give items an explicit type: :object which got rid of the additonal keys, but always included an additional empty object definition inside anyOf:

{
  "type": "object",
  "properties": {
    "an_array": {
      "type": "array",
      "items": {
        "anyOf": [
          {
            "type": "object",
            "properties": {
            }
          },
          {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              }
            }
          },
          {
            "type": "object",
            "properties": {
              "age": {
                "type": "number"
              }
            }
          }
        ]
      }
    }
  }
}

Solution:

I solved this now by specifying the possible objects using

items any_of: [
  object { string(:name) },
  object { number(:age) }
]

which results in the correct output.

Shouldn't any_of as an option to items and when being used inside items have the same result? At least it looked this way from the terse/verbose examples.

Feature request: Ability to extend JSON Schema, eg. additional keywords

It would be nice if we were able to add additional keywords, like

object do
  string :name
  string :notes, 'x-scope': :admin
end

In this example I'm adding a key called x-scope, to indicate that it's a custom attribute. But it might as well be scope without the x-.

The resulting JSON would look like this

{
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "notes": { "type": "string", "x-scope": "admin" }
  }
}

This is allowed according to the spec. See chapter "Extending JSON Schema". Although it's in draft, if I'm correct.
https://json-schema.org/draft/2019-09/json-schema-core.html#extending

Do you think this is something you'd like to add?

If yes, I'm willing to implement it and create a Pull Request.

Avoid create empty "required" property

When you have an object and you force required: false on at least one attribute, but none are required : true, it will still creates a "required" property with an empty array

schema = object do
  string :my_key, required: false
  string :my_other_key, required: true
end.as_json
# => {"type"=>"object", "required"=>["my_other_key"], "properties"=>{"my_key"=> {"type"=>"string"}, "my_other_key"=>{"type"=>"string"}}}

schema = object do
  string :my_key
  string :my_other_key
end.as_json
# => {"type"=>"object", "properties"=>{"my_key"=>{"type"=>"string"}, "my_other_key"=>{"type"=>"string"}}}

schema = object do
  string :my_key
  string :my_other_key, required: false
end.as_json
# => {"type"=>"object", "required"=>[], "properties"=>{"my_key"=>{"type"=>"string"}, "my_other_key"=>{"type"=>"string"}}}

Extending objects with `null: true` causes a StackLevelTooDeep exception

Hi again ๐Ÿ˜…

today I ran into a problem when using the functionality implemented in #8: If I build a schema by extending an existing object instead of nesting everything and assigning null: true, a StackLevelTooDeep exception will be thrown.

As this seems to only happen with null as attribute which is internally translated to an any_of, I would suspect that it has something to do with this.

I will investigate a bit further myself, but maybe you have an idea what exactly is causing this instantly.
I find myself having a few problems following the gem's working due to its architecture.


The following is the smallest example I could produce that still causes the error.
It will print the stacktrace once its size reaches 3000.

#!/usr/bin/env ruby

require 'json/schema_builder'

trace_func_proc = proc do |event, file, line, id, binding, classname|
  if event == 'call' && caller.length > 3000
    puts caller
    exit(1)
  end
end

set_trace_func(trace_func_proc)

class SchemaStack
  include JSON::SchemaBuilder

  def schema
    obj = object :bar, null: true
    obj.string :baz
    obj
  end
end

SchemaStack.new.schema.as_json

The repeating portion seems to be:

/Users/stex/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/json-schema_builder-0.8.2/lib/json/schema_builder/entity.rb:141:in `extract_types'
/Users/stex/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/json-schema_builder-0.8.2/lib/json/schema_builder/object.rb:30:in `extract_types'
/Users/stex/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/json-schema_builder-0.8.2/lib/json/schema_builder/object.rb:35:in `reinitialize'
/Users/stex/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/json-schema_builder-0.8.2/lib/json/schema_builder/attribute.rb:16:in `block in attribute'
/Users/stex/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/json-schema_builder-0.8.2/lib/json/schema_builder/entity.rb:142:in `extract_types'
/Users/stex/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/json-schema_builder-0.8.2/lib/json/schema_builder/entity.rb:46:in `initialize'
/Users/stex/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/json-schema_builder-0.8.2/lib/json/schema_builder/dsl.rb:11:in `new'
/Users/stex/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/json-schema_builder-0.8.2/lib/json/schema_builder/dsl.rb:11:in `entity'
/Users/stex/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/json-schema_builder-0.8.2/lib/json/schema_builder/dsl.rb:45:in `block (2 levels) in register'

Thanks a lot in advance!

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.