voxpupuli / json-schema

Ruby JSON Schema Validator
MIT License
1.54k stars 243 forks source link

Is there a method available to get a fully resolved schema as a hash? #32

Open bruno-c opened 12 years ago

bruno-c commented 12 years ago

Is it possible to retrieve the schema that is constructed internally for validation, including extends, $ref'ed schemas, etc as one fully 'resolved' json-schema hash?

I did not have the time to investigate the internals of the gem yet so I thought i'd ask first. I wrote a half-assed implementation myself for my purposes (documentation of the schema) but I figured this might be something that would be useful to others as well.

Thank you.

hoxworth commented 12 years ago

There isn't a method for this yet, no, but it's something that could be done. The biggest problem is resolving cyclic dependencies, so printing out the "fully resolved" schema would have to check for this. I've marked this as a todo feature for a future release.

nickl- commented 11 years ago

It would seem salesking/json_schema_tools is already doing this, but since I still haven't actually implemented it myself it is purely speculation, worth checking out?

commonsguy commented 10 years ago

I'll echo the original request. In order to build tools that use JSON Schema (code generators, documentation generators, test data generators, etc.), we need a JSON Schema parser that gives us the JSON Schema, ideally as actual Ruby objects. All the Ruby implementations that I have seen -- including this one and https://github.com/salesking/json_schema_tools -- appear to consider the decoded schema to be internal implementation, solely to support their own tools (e.g., this gem's validation logic).

pd commented 9 years ago

I'm not sure this is even possible, at heart. Self-referencing schemas are a core feature of json-schema; the metaschemas themselves use it extensively (eg, here, here, etc).

We couldn't possibly expand that entirely -- it's infinitely recursive.

Anyone aware of any JSON schema library that provides something approaching this feature? I'd be curious what they do to deal with it.

commonsguy commented 9 years ago

@pd: I would expect that it would point new references to existing nodes in the object graph, when those references are to previously-referenced schemas.

pd commented 9 years ago

Ah, that makes sense. I was interpreting it as essentially eliminating all $refs.

By actual ruby objects, do you mean Plain Ol Hashes, or specialized objects that provide more behavior?

I'm willing to try my hand at this if someone could spec out more exact requirements / a more detailed use case. If its just "resolve absolute $refs and spit out a hash", it should be pretty simple. But if its more than that, I'd need a better idea of what API to aim for.

commonsguy commented 9 years ago

"By actual ruby objects, do you mean Plain Ol Hashes, or specialized objects that provide more behavior?"

Well, AFAICT, I mean what you already have, such as Attribute and its subclasses. You appear to be building up the data model that I (and others) could use; you just aren't providing a way to actually get to it, at least in a documented fashion. I'm no expert at your code base, but it might be as simple as exposing @base_schema, since that seems to be what validate() uses.

"I'm willing to try my hand at this if someone could spec out more exact requirements / a more detailed use case"

In terms of use cases, your own validation is one use case: you are using your data model of the parsed schema(s) to validate an object. Instead of thinking of this project as a JSON validator, think of it as a JSON schema parser that also happens to ship a JSON validator. In terms of other use cases, I listed a few in my original comment, such as test data generators (given a schema, generate X random objects that comply with the schema, plus objects for testing validation errors).

pd commented 9 years ago

Yup, totally makes sense. Despite the name of the library, the JSON::Schema object is mostly unused in the current codebase; 90% of the code here lives in JSON::Validator or something it calls. All of the FooAttribute classes are really just namespaces for hanging a .validate class method off of; they don't get instantiated or exposed to users in any way.

I'll try to keep this in mind, but I don't have any clear ideas for how to refactor things in that direction just yet. =\

As an aside, I just mentioned in #120 that I stumbled upon a gem genny today; might be worth checking out if you're looking for test data generation. I was too!