Making Use of Inheritance when generating GraphQL Schemas

Hi there

I've been trying Stardog's support for GraphQL and it's really cool what one can do without having to write any resolvers etc. I especially like the explain feature.

I have been able to generate a GraphQL schema for my SHACL shapes (--input SHACL) using some ontology information that state rdfs:subClassOf relations (via --schema). I have looked at the Starwars example and noticed that you use an interface in the GraphQL schema to express subclass relations between classes.

Is there a way to also generate these interfaces when using stardog data model? Otherwise the "subclass" types lack the superclass's properties.

Thanks for any hint.

Hi Tobias,

Welcome to the Stardog Community and glad to hear you like the GraphQL feature.

Auto-schema generation does not use interfaces because what you can do with GraphQL interfaces is quite limited compared to RDFS/OWL class hierarchies. Most notably, interfaces cannot extend other interfaces which limits their usage except to simple cases like the one we used in our example. (Note: The latest working draft of the GraphQL spec introduces the possibility for interface extensions so we might leverage this feature in the future).

What we currently so in schema generation is use types for every class and repeat the field definitions in each subclass to mimic the affects of inheritance. So if you generate the GraphQl schema from the starwars schema you should see:

type Character {
  appearsIn: [Episode]
  friends: [Character]
  id: Int
  iri: ID!
  name: String
}

type Droid {
  appearsIn: [Episode]
  friends: [Character]
  id: Int
  iri: ID!
  name: String
  primaryFunction: String
}

This is not an ideal solution but superclass properties should not be missing from subclasses. If you have an example where this does not work please share that with us.

Best,
Evren

Hi Evren,

Thanks a lot for your reply. I'll try to provide a minimal example.

shapes.json contains SHACL shapes for schema:Thing and schema:Person (we are using sh:targetClass). ontology.json expresses the subclass relation between person and thing.
Now when this data is loaded using load_shapes.sh, I get the following result:

schema {
  query: QueryType
}

type Organization @iri(value : "http://schema.org/Organization") {
  iri: ID!
}

type Person @iri(value : "http://schema.org/Person") {
  additionalName: [String] @iri(value : "http://schema.org/additionalName")
  address: String @iri(value : "http://schema.org/address")
  affiliation: [Organization]! @iri(value : "http://schema.org/affiliation")
  birthDate: String @iri(value : "http://schema.org/birthDate")
  deathDate: String @iri(value : "http://schema.org/deathDate")
  email: String @iri(value : "http://schema.org/email")
  familyName: String! @iri(value : "http://schema.org/familyName")
  givenName: String! @iri(value : "http://schema.org/givenName")
  honorificPrefix: String @iri(value : "http://schema.org/honorificPrefix")
  honorificSuffix: String @iri(value : "http://schema.org/honorificSuffix")
  iri: ID!
  jobTitle: [String]! @iri(value : "http://schema.org/jobTitle")
}

type QueryType {
  Organization: Organization
  Person: Person
  Thing: Thing
}

type Thing @iri(value : "http://schema.org/Thing") {
  alternateName: [String] @iri(value : "http://schema.org/alternateName")
  description: ID @iri(value : "http://schema.org/description")
  identifier: ID @iri(value : "http://schema.org/identifier")
  image: ID @iri(value : "http://schema.org/image")
  iri: ID!
  name: String! @iri(value : "http://schema.org/name")
  sameAs: [ID] @iri(value : "http://schema.org/sameAs")
  url: [ID] @iri(value : "http://schema.org/url")
}

Regarding the generated schema, I have the following comments:

  1. I'd expect person to have also the properties / fields defined for thing.

  2. I also noticed that QueryType lacks the @iri decorators resulting in SPARQL queries that return no result, same as described here.

  3. How is sh:or handled? If two datatypes are allowed on a property's range, will there be a union in the schema?

I've gained some experience in transforming the shapes graph for different purposes. Maybe the shapes need some more info (they do not contain inheritance info directly, only indirectly via their target classes)?

Thanks a lot for your feedback.

Kind regards,

Tobias

shapes.json (8.8 KB)
ontology.json (1.3 KB)
load_shapes.sh (352 Bytes)

Hi Tobias,

  1. You are exactly right about shapes needing inheritance info explicitly. If a shape contains sh:node AnotherShape then all the properties defined in that shape will be inherited. Currently selecting the input format SHACL means all RDFS/OWL information is ignored but you raise a good point that using SHACL for properties and RDFS/OWL for inheritance makes sense.

  2. We will take a look at this.

  3. No, currently, for the purposes of schema generation, sh:or is ignored.

Best,
Evren

Hi Evren,

Thanks a lot for your response.

Is the code used for GraphQL schema generation open-source?
What about the translation from GraphQL to SPARQL, is this code open-source?

I am asking because I am interested to know how you do this :slight_smile: and secondly I'd be glad to contribute something sometime.

Kind regards,

Tobias

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.