datacontract / datacontract-specification

The Data Contract Specification Repository
https://datacontract.com/
MIT License
223 stars 34 forks source link

Complex definitions #78

Open simonharrer opened 1 month ago

simonharrer commented 1 month ago

Definitions can be of type object. Definitions can have fields.

emirkmo commented 1 month ago

As part of the update, can you also look at how Definitions are meant to be treated especially when they add on to existing Objects?

What should happen in case type is defined in both Field and in the Definition that is linked via $ref:?

Currently Definitions require type which makes it ambiguous whether type must be removed from Field, is overwritten by the definition, or the definition should do a merge without overwriting. I know the detail of this can be worked out in the CLI/tooling, but it would be good to explicitly clarify if a definition can/should "extend" attributes of a field or it should replace them, and which one takes precedence in case of collision, since definitions are meant to be used with $ref.

This matters since Definitions seem like an ideal candidate for a part of the contract that gets filled in with increasing maturity: "This can be iterated on in later versions of the contract".

Alternatively to $ref, you could look at allowing inline Definition within the attributes of a Field or Model, nesting them as definition:, meaning definition field of other objects would be of type string | Definition Object. This allows side-stepping the ambiguity with $ref and also stops many objects from growing boundlessly, as the Definition Object can subsume a lot of that growth... (Arbitrary entries in at least Field are allowed already anyway according to the json schema, so one can add a Definition object there, but it does not follow the README).

field:
   type: [FieldType]
   definition: [String | Definition]
   # or
   $ref: 'definitions.modelXfieldY' # must we remove 'type' from field? Which takes precedence?

I think the latter also makes Definition a more universal object. Since a model or something else may have a complex Definition, but may not have a type, which is currently required.