json-schema-org / vocab-idl

Help and clarify how JSON Schema can be interpreted from validation rules to data definition. This extends to how those data definitions can be represented in any programming language
19 stars 4 forks source link

Simple objects #46

Open gregsdennis opened 1 year ago

gregsdennis commented 1 year ago

For this conversation, a "simple" type is a type that inherits from (essentially) nothing.

A mostly universal concept is that a simple type has named properties. Thus the most basic JSON Schema representation for a simple type should be

{
  "type": "object",
  "properties": {
    // ...
  }
}

where the type's properties are listed in properties.

I don't think there's any opposition to this idea.

There are some edge cases that should be looked at, though.

OOP and enumerated/collection types

In primarily OOP languages (Java, .Net, Objective-C), arrays and other enumerated types are also objects. These should be defined as arrays, not objects. I'll (eventually) open another issue about these enumerated/collection types. For now, I want to focus on simple types.

There is even an edge-edge case. In C#, it's legal to add properties onto these types. So for instance

class MyList : List<int>
{
    public string Foo { get; set; }
}

(By default, the .Net JSON serializer ignores these properties and just serializes the collection.)

The inheritance implies this is a collection of items, but the declaration has properties. I'll (eventually) open another issue to discuss inheritance, and I think this case would better fit there.

Open-ended key/value pair collections types

.Net calls these types "dictionaries."

There are two cases here:

  1. the key either is a string or can be represented by one (e.g. dates, enums)
  2. the key cannot be represented by a string (i.e. some complex object that hashes uniquely)

For (1), although the keys aren't exactly properties, these types are still serialized into JSON as objects. (This only works because JSON object keys are themselves strings.) You may think that this complicates determining a simple type from a dictionary, but because of the open-ended nature, a JSON Schema that describes a dictionary should actually use additionalProperties instead of properties.

{
  "type": "object",
  "additionalProperties": {
    // ...
  }
}

For (2), the only recourse is to serialize into an array where every item has key and value properties. Moreover, every key must be unique (something that JSON Schema can't enforce currently, but my uniqueKeys vocab could help with).

{
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "key": {
        // ...
      },
      "value": {
        // ...
      }
    }
  }
}

Dictionary types also have the same edge-edge case as collections in that it's possible to inherit from one of these types and explicitly add properties. (Like the above case, by default, the .Net JSON serializer ignores these properties and just serializes the dictionary.)