Let's say that I have a class called "Event". Inside of this class there is a property called chanceOfSuccess which has the type QuantitativeValue. QuantitativeValue is a class that has min, max, and value properties.

Depending on the event, the min and max value can be different, but would have the semantic of constraining what the value of chanceOfSuccess should be and would be enforced in code.

How would I design this on the json-ld side?

One method would be to create a subclass of Event and create a property called chanceOfSuccess30_60. The min and max values could be parsed from the property name or the code could have an if statement which looks for chanceOfSuccess30_60 and knows to enforce a value of 30 to 60 on the value of chanceOfSuccess30_60. This would seem bad.

Alternatively, I would think it possible to define a subclass of QuantitativeValue, called QuantitativeValue_30_60, where min value is 30 and max value is 60. A subclass of Event then has a property with the type QuantitativeValue_30_60. Code can then see it is dealing with an instance of a subclass of QuantitativeValue and know to look at the min and max value to constrain the value of the instance. However, this seems to be overly complex as it would require a subclass for every possible combination of min and max value and be no better then the first alternative.

A third alternative might be when creating the instance of an Event, to set the min and max value at that time. This would seem to be the best option, but would seem to shift to much responsibility onto the code creating and managing the instances.

The fourth alternative would be to use SHACL. In this case, for every subclass of Event, I would need to define an equivalent Shape instance which targets that class. This would seem similar to the second alternative, but instead of using the min and max value properties in QuantitiveValue to hold the constraints, the constraints are in the Shape instance. 

However, I am not certain as I am approaching this from a practitioner perspective and one who is just beginning to learn about these ideas.

Is there a fifth alternative I have not considered?

Are one of these four the correct path? If so, again, what would the design look like from the json-ld side?


Based on my research into this topic there appears to be two reasonable solutions. Perhaps one solution is more reasonable then the other.

One key is to recognize that constraints exist as a concept outside of the instance of a class and should be outside of the actual instance data.

The first solution is to adopt SHACL. It is a W3C recommendation and supported project. It provides a well defined, generic, and powerful system for applying constraints to properties. There are standard libraries which implement SHACL which provide enforcement for free. The caveat here is that adopting SHACL may provide more power and flexibility than is needed by a project and the overhead of maintaining Shape files may not be worthwhile. Whether this is an issue will only be known with time and experience as the technology is new.

The second solution follows this general model:

  "@id": "http://my-company.org/chanceOfSuccess",
  "@type": "rdf:Property",
  "http://schema.org/domainIncludes": {
    "@id": "http://my-company.org/Event"
  "http://schema.org/rangeIncludes": {
      "@id": "http://schema.org/QuantitativeValue"
  “ex:chanceMinValue” : “30”,
  “ex:chanceMaxValue” : “60”,
  "rdfs:comment": “Allow values are only 30-60.",
  "rdfs:label": “chanceOfSuccess with range 30-60"

In this case, we declare the property and as part of that declaration, the constraints are encoded. How these constraints are defined and enforced is up to the particular project using the objects. At a minimum, code needs to be written which may not be available outside of the project to enforce the constraints.

The SHACL solution is the one I will be going with for now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.