GraphQL ...on SubClass/SubShape

154 views
Skip to first unread message

Davide Sottara

unread,
Nov 20, 2023, 11:35:42 PM11/20/23
to TopBraid Suite Users
I have a class hierarchy, where the classes are also node shapes with property shapes

class AA
   propA :String

class BB subClassOf AA
  propB : String

Is a query like the following supported?

aaas {
   propA
    ... on bbb {
     propB
  }
}

Thank you

Holger Knublauch

unread,
Nov 21, 2023, 3:55:51 PM11/21/23
to 'Bohms, H.M. (Michel)' via TopBraid Suite Users
Have you tried it out? What happened?

Holger


--
The topics of this mailing list include TopBraid EDG and related technologies such as SHACL.
To post to this group, send email to topbrai...@googlegroups.com
---
You received this message because you are subscribed to the Google Groups "TopBraid Suite Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to topbraid-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/efa87ebe-4872-42f7-aaa7-27fc8dcadbb1n%40googlegroups.com.

Davide Sottara

unread,
Nov 21, 2023, 9:59:38 PM11/21/23
to TopBraid Suite Users
Unfortunately I get an error
"Fragment cannot be spread here as objects of type (super) can never be of type (sub)

Holger Knublauch

unread,
Nov 22, 2023, 2:44:58 AM11/22/23
to topbrai...@googlegroups.com
Hi Davide,

thanks for the error message. I had to read up on GraphQL fragments as I have never used them.
It seems that they would need to be declared using the fragment keyword but I don't see that in your query.
Our GraphQL engine does not declare such fragments automatically.

It would streamline this discussion if we had a complete, self-contained example.

Thanks
Holger


Davide Sottara

unread,
Nov 28, 2023, 9:08:10 AM11/28/23
to TopBraid Suite Users
I have put together a simple ontology with a class hierarchy, a property on each class, and one individual per class - attached
AAA
  DDD
  BBB
    CCC

I was looking for a behavior that replicates unions or interfaces:
https://www.apollographql.com/docs/apollo-server/schema/unions-interfaces/

In fact, have tried setting graphql:isInterface = true, but that does not seem to have any effect?

Thank you for any insight\
Davide

HierarchicalDataGraphTest.trig

Holger Knublauch

unread,
Nov 28, 2023, 11:02:09 AM11/28/23
to topbrai...@googlegroups.com

On 28 Nov 2023, at 3:08 pm, Davide Sottara <dso...@gmail.com> wrote:

I have put together a simple ontology with a class hierarchy, a property on each class, and one individual per class - attached
AAA
  DDD
  BBB
    CCC

Thanks for the file, which I was able to play with. I also tried something like

{
   aaas {
    uri
    ... on BBB {
      propA
    }
  }
}

but since the schema doesn't know the relationships between AAA and BBB this doesn't work. All types in the generated schemas are independent, no implements or such.


I was looking for a behavior that replicates unions or interfaces:
https://www.apollographql.com/docs/apollo-server/schema/unions-interfaces/

In fact, have tried setting graphql:isInterface = true, but that does not seem to have any effect?

graphql:isInterface is only used for round-tripping GraphQL Schema files from elsewhere, not those that are auto-generated.

So I am afraid this syntax isn't working and you may need to revert to other technologies like SPARQL or ADS JavaScript to formulate such queries.

Holger


To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/eb1d3a18-c776-4924-b365-8f0de0e16cc0n%40googlegroups.com.
<HierarchicalDataGraphTest.trig>

Holger Knublauch

unread,
Nov 28, 2023, 2:07:33 PM11/28/23
to 'Bohms, H.M. (Michel)' via TopBraid Suite Users
One more thought: it seems like you want to dynamically cast from one type to another. You can theoretically do that through a virtual property that points at the instance itself but with a different declared sh:class. Add these triples to your ontology;

hst:AAA
sh:property hst:AAA-asBBB .

hst:AAA-asBBB
  a sh:PropertyShape ;
  sh:path hst:asBBB ;
  dash:hidden true ;
  sh:class hst:BBB ;
  sh:maxCount 1 ;
  sh:name "as BBB" ;
  sh:values [
      sh:filterShape [
          sh:class hst:BBB ;
        ] ;
      sh:nodes sh:this ;
    ] ;
.

This computes an inferred value that has as values the focus node itself (sh:this), but declared as BBB via sh:class. It uses a filterShape to return null if the focus node is NOT an instance of BBB. 

You can then formulate queries such as

{
   aaas {
    uri
    asBBB {
      propB
    }
  }
}

with an example output such as

{
  "data": {
    "aaas": [
      {
        "asBBB": null
      },
      {
        "asBBB": null
      },
      {
        "asBBB": {
          "propB": "valueB"
        }
      },
      {
        "asBBB": {
          "propB": "valueBC"
        }
      }
    ]
  }
}

Note this approach already works but is a compromise:

1) It requires changes to the ontology for all cases where you want to typecast
2) It probably returns a different nesting in the result JSON (not sure)?

Does this help?

Holger

Davide Sottara

unread,
Nov 28, 2023, 11:02:13 PM11/28/23
to TopBraid Suite Users
This is quite interesting, thank you!

1) Yes - but combined with other workarounds, such as pushing the property shapes up the hierarchy, or querying multiple subclasses in parallel, provides options
2) Yes - it changes the structure with respect to a common interface/union class, which we don't have anyway (!)

Davide

Out of curiosity: if there was a way for users to declare unions or interfaces via a triple in the graphql: namespace, so that the union/interface declaration could be
added to the GraphQL schema, would the GraphQL engine in EDG work out of the box?

Holger Knublauch

unread,
Nov 29, 2023, 7:32:08 AM11/29/23
to topbrai...@googlegroups.com
The difficulty for the mapping between SHACL and GraphQL is that GraphQL has a weak notion of classes and inheritance. I had tried to work with interfaces originally but didn't get far, so ended up with a structure in which all GraphQL types are independent of each other, and thus no dynamic casting or unions work. Changing these design choices now that so many customers depend on it would be extremely hard.

So I am afraid you need to work with what's there, or move to other technologies that offer more flexibility over GraphQL.

Holger


Reply all
Reply to author
Forward
0 new messages