sqlalchemygraphqlvirtuoso

How to achieve compliance between Graphql in Virtuoso and Python graphql-db-api


Recent additions of GraphQL views to Open Link Virtuoso motivated to make one more attempt of using data from Virtuoso in Apache Superset.

For that purpose, Python lib graphql-db-api may be used. It provides needed integration with SQLAlchemy and Superset works well with GraphQL endpoints used in the graphql-db-api examples.

However attempts at using that library to retrieve data from Virtuoso GraphQL endpoints did not give positive results.

Investigation shows that graphql-db-api expects an explicit top-level type of NON_NULL kind in the GraphQL schema, but Virtuoso does not use such top-level type in its own GraphQL schema.

For example, GraphQL endpoint graphql://pet-library.moonhighway.com has the following fragment of schema:

    {
        "data": {
            "__schema": {
                "queryType": {
                    "fields": [
                        {
                            "name": "allPets",
                            "type": {
                                "name": null,
                                "kind": "NON_NULL",
                                "ofType": {
                                    "name": null,
                                    "kind": "LIST",
                                    "ofType": {
                                        "kind": "NON_NULL",
                                        "name": null,
                                        "ofType": {
                                            "name": "Pet"
                                        }
                                    }
                                }
                            }
                        },

The field allPets has a top-level type of kind NON_NULL and only after that the type of kind LIST follows.

While a Virtuoso-hosted GraphQL endpoint returns the following schema:

{
    "data": {
        "__schema": {
            "queryType": {
                "fields": [
                    {
                        "name": "ConceptSchemes",
                        "type": {
                            "name": null,
                            "kind": "LIST",
                            "ofType": {
                                "name": "ConceptScheme",
                                "kind": "OBJECT",
                                "ofType": null
                            }
                        }
                    }

Here the field ConceptSchemes has only a type of kind LIST.

Is it possible to configure GraphQL views in Virtuoso with additional level of the top-level type with NON_NULL kind?


Solution

  • It looks like you're trying RDF linked data views via GraphQL bridge and talking about a GraphQL introspection query result used by the Python application/driver.

    Thus you are doing TTLP(GQL_CREATE_TYPE_SCHEMA ('rdf view generated schema graph IRI')) as described here.

    The above statement imports a Turtle document describing the introspection graph for the RDF view; therefore it contains statements for Query type, like this —

    :Query :fields [ :name "Products" ; :type [ :kind "LIST" ; :ofType ns0:Products ] ] .

    If you want to make Products lists non-null, you have to save the result from GQL_CREATE_TYPE_SCHEMA(), for example via string_to_file() function, and then modify the above statement in the Turtle document to —

    :Query :fields [ :name "Products" ; :type [ :kind "NON_NULL"; :ofType [ :kind "LIST" ; :ofType ns0:Products ] ] ] .

    — or you could use your own SDL like this —

    type Product {
      ProductId: ID!
      ProductName: String!
      # etc.
    }
    
    type Query {
      Products: [Product!]!
    }
    

    — and make a Turtle document for the introspection graph via GQL_GENERATE_INTRO([sdl document]).

    Once triples declared for this particular kind of array are not nullable, you should import and register into the Graphql bridge introspection graph.