Git Product home page Git Product logo

Comments (10)

gregsdennis avatar gregsdennis commented on May 23, 2024 2

@sbiaudet have a look at ☝️ and let me know if that's what you had in mind.

I've done the simple types. array should be pretty easy, but object will get rather complex. object is where we can start to introduce attributes for additional requirements such as string length or max value.

The plan is to use it like this:

var schema = new JsonSchemaBuilder().FromType<MyType>();

from json-everything.

gregsdennis avatar gregsdennis commented on May 23, 2024

Thanks for the suggestion!

Schema generation doesn't seem to me a core function, and I'm really trying to keep this library as simple as possible. Maybe this would work in an extension library (still defined in this repo).

Also, there's a bunch of stuff to consider for generation, like complexity.

Schemas generated from JSON instances naturally cannot be very complex because not much information is given in a single instance. A more advanced scenario is that more complex schemas could be derived from multiple passing or failing instances.

Generation from a type can have a level of complexity because types can give a bit more information regarding valid values.

I also see the opportunity for quite a few options.

I'd like to sit on this one for a bit as I'm working on other things right now, but it does sound like a good idea for an extension library that makes use of the JsonSchemaBuilder.

If you have any thoughts on the rules around how instances or types can be translated, please be sure to take notes here.

from json-everything.

gregsdennis avatar gregsdennis commented on May 23, 2024

Examples of complexity from instance data:

{ "property": 5 }
  • Is this an integer, or just a general number?
  • Are there range requirements (min / max)?
  • Is property required?
{ "property": "Value" }
  • Is Value just a string, or is it one possible value in a finite collection of valid values (an enum)?
  • Are there any formatting / length / regex requirements if it's just a string?
[ 1, "string", true ]
  • Is there a min / max item count?
  • Are these the only valid values?
  • Are these valid in this sequence, but perhaps not valid in a different sequence (items keyword with an array of schemas)?

One approach is to generate the simplest schema, but in practice, you'll still have to edit the schema to get what you want. So at best, this gets you a minimal starting point. I'd argue that such a minimally viable schema is isn't going to save you much work.

If we do this for these examples, we'd end up with the following schemas, respectively:

{
  "type": "object",
  "properties": {
    "property": { "type": "integer" }
  }
}

{
  "type": "object",
  "properties": {
    "property": { "type": "string" }
  }
}

{
  "type": "array",
  "items": true
}

To get better schemas, you ideally want to give multiple examples of passing and failing instances (telling the system which pass and which fail). But again, this adds to the complexity.

from json-everything.

sbiaudet avatar sbiaudet commented on May 23, 2024

I’m agree with you. You can obtain only a very simple schema. It’s like when you use serialize. The serializer make some choice for you.

In a first step I think your solution is acceptable. But after we should add attributes to specified custom schema generation.

from json-everything.

gregsdennis avatar gregsdennis commented on May 23, 2024

Attributes work fine on a type in code, but you can't do that with a JSON instance. This is the difficult case.

from json-everything.

sbiaudet avatar sbiaudet commented on May 23, 2024

You're right

from json-everything.

sbiaudet avatar sbiaudet commented on May 23, 2024

Perhaps having FromObject method is a better approach. And we don't use json string. You're feeling ?

from json-everything.

sbiaudet avatar sbiaudet commented on May 23, 2024

@gregsdennis great job. It's seems to be cool. I love it.

from json-everything.

gregsdennis avatar gregsdennis commented on May 23, 2024

Okay. I'm to a good point, I think. I have it turning this

class GenerationTarget
{
	[Required]
	[Minimum(5)]
	[ExclusiveMinimum(4)]
	[Maximum(10)]
	[ExclusiveMaximum(11)]
	[MultipleOf(1.5)]
	public int Integer { get; set; }

	[MaxLength(10)]
	[Pattern("^[a-z0-9_]$")]
	public string String { get; set; }

	[MinItems(5)]
	[MaxItems(10)]
	public List<bool> ListOfBool { get; set; }

	[MinLength(5)]
	[UniqueItems(true)]
	[Obsolete]
	public List<string> ListOfString { get; set; }

	[Maximum(100)]
	public int Duplicated1 { get; set; }

	[Maximum(100)]
	public int Duplicated2 { get; set; }

	public GenerationTarget Target { get; set; }
}

into this

{
  "type": "object",
  "properties": {
    "Integer": {
      "type": "integer",
      "exclusiveMaximum": 11,
      "exclusiveMinimum": 4,
      "maximum": 10,
      "minimum": 5,
      "multipleOf": 1.5
    },
    "String": {
      "type": "string",
      "maxLength": 10,
      "pattern": "^[a-z0-9_]$"
    },
    "ListOfBool": {
      "type": "array",
      "items": {
        "type": "boolean"
      },
      "maxItems": 10,
      "minItems": 5
    },
    "ListOfString": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 5
      },
      "uniqueItems": true,
      "deprecated": true
    },
    "Duplicated1": {
      "$ref": "#/$defs/integer"
    },
    "Duplicated2": {
      "$ref": "#/$defs/integer"
    },
    "Target": {
      "$ref": "#"
    }
  },
  "required": [
    "Integer"
  ],
  "$defs": {
    "integer": {
      "type": "integer",
      "maximum": 100
    }
  }
}

This example shows:

  • all of the supported attributes, which are all defined within this assembly (except for Obsolete),
  • generics support
  • consolidating common subschemas into $defs
  • recursive definition detection

from json-everything.

sbiaudet avatar sbiaudet commented on May 23, 2024

@gregsdennis it's great. I think you have an elegant solution. It's simply and powerful for complex usage.

from json-everything.

Related Issues (20)

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.