GraphQL schemas and endpoint management¶
What’s in this document?
GraphDB lets you create GraphQL endpoints that provide API access to a GraphDB repository’s data, treating the repository’s classes and properties as GraphQL types and fields. To do this, GraphDB generates a GraphQL schema that specifies the structure of this interface.
There two are ways to provide input for this process: a GraphQL Schema Shapes model or a set of OWL ontologies and SHACL shapes. See the Creating GraphQL endpoints section for an overview of the two.
After you have used one of these approaches to create a GraphQL endpoint for one of your repositories, the GraphiQL Explorer tool that is built in to Workbench’s GraphQL Playground gives you a visual way to explore the new API. It lets you create queries and also mutations that can add to, delete, and modify the data. Queries and mutations can then be programatically sent to the endpoint using the GraphDB REST API.
Creating GraphQL endpoints¶
From Workbench, selecting takes you to the Endpoint Management screen. The New endpoint button on this screen takes you to the New endpoint screen.
The Source repository for you new endpoint will be set to the currently connected one, but you can use the dropdown list near the top of this screen to select another one.
Underneath that, select the radio button indicating whether you want to create the schema from GraphQL Schema shapes or OWL Ontologies/SHACL shapes. Each of these offers certain advantages depending on the input you are using to configure the new schema. Select one of the links in the following list for details on using that method:
GraphQL schema shapes: Describe your data structures with a GraphQL model that uses the GraphQL Data Shapes vocabulary to specify the high-level structure and SHACL to specify details about the types and fields to make available via the API. This method is best when you want to have more control over the GraphQL schema that gets generated.
OWL ontologies/SHACL shapes: Identify existing RDFS schemas, OWL ontologies, and SHACL shapes to use as input for GraphDB’s API generator. This method is best when you want to quickly generate a GraphQL schema from models that you already have.
Creating a GraphQL interface from GraphQL schema shapes¶
When you create a GraphQL endpoint in Workbench by selecting and then New endpoint, the GraphQL schema shapes option lets you create one using a GraphQL Schema Shapes model. The creation and tuning of this model lets you customize the appearance and behavior of the GraphQL API and endpoint that you are creating.
To do this, the GraphQL Data Shapes vocabulary provides classes and properties that you can use to define a GraphQL Schema Shapes model. GraphDB can then use this model to generate a GraphQL schema, endpoint, and API.
Preparing the model to load¶
A GraphQL Schema Shapes model consists of:
An instance of
graphql:Schemafrom that vocabulary.Properties of that instance to describe the schema’s structure.
Any supporting shapes, RDFS, and OWL classes necessary to describe the classes and properties that will be exposed as types and fields in the GraphQL API being generated.
The GraphQL Schema Shapes model is typically stored in the repository with the instance data that it describes so that once the model is used to generate a GraphQL schema and endpoint, GraphQL queries will return instance data from that repository via the endpoint whose API is defined by this model.
You can use multiple GraphQL Schema Shapes models to generate multiple GraphQL APIs for a single repository, with each API providing a different view of the repository’s data. When you are connected to a repository that has any of these models defined, selecting in Workbench and then New endpoint will show you any graphql:Schema shapes defined for that repository in the Available list.
The following shows an example GraphQL Schema Shapes model. After declaring e:EmpSchema as an instance of graphql:Schema, it has an rdfs:label value and two graphql:publicShape properties to point to shapes that represent data classes in that repository. The rest of the schema is all SHACL statements to describe those classes and their relationship.
@prefix e: <http://example.com/ns/model/employee#> .
@prefix graphql: <http://datashapes.org/graphql#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
e:EmpSchema a graphql:Schema;
rdfs:label "Employee GraphQL Schema" ;
graphql:publicShape e:EmployeeShape ;
graphql:publicShape e:AddressShape .
e:EmployeeShape a sh:NodeShape ;
sh:targetClass e:Employee ;
sh:property [ rdf:type sh:PropertyShape ;
sh:datatype xsd:string ;
sh:path e:familyName
] ;
sh:property [ rdf:type sh:PropertyShape ;
sh:datatype xsd:string ;
sh:path e:givenName
] ;
sh:property [ rdf:type sh:PropertyShape ;
sh:datatype xsd:date ;
sh:path e:startDate
] ;
sh:property [ rdf:type sh:PropertyShape ;
sh:class e:Address ;
sh:path e:address
] .
e:AddressShape a sh:NodeShape ;
sh:targetClass e:Address ;
sh:property [ rdf:type sh:PropertyShape ;
sh:datatype xsd:string ;
sh:path e:street
] ;
sh:property [ rdf:type sh:PropertyShape ;
sh:datatype xsd:string ;
sh:path e:city
] .
This example uses a limited range of SHACL features, but you can use additional ones to create a more sophisticated model. As described later in this chapter, the GraphQL Data Shapes vocabulary includes additional constructs that you can add to this model to define more details about the generated GraphQL shapes. Still, with a minimal GraphQL Schema Shapes model like the one shown above, you can generate a GraphQL schema that looks like the following when viewed with the GraphiQL Explorer tool that is included with Workbench:
See Querying GraphQL endpoints in Workbench for more on using this tool.
Loading the model and creating the GraphQL schema¶
If your currently connected repository has a GraphQL Schema Shapes model in it, then when you create a new GraphQL endpoint and select GraphQL schema shapes on the New endpoint screen, you will see a GraphQL schema shape listed under Available (not included) for each graphql:Schema defined in repository’s data. Below, we see two listed there:
Clicking the Add the shape to the list of included shapes icon to the right of any available GraphQL Schema Shape in that list will move it over to the Included for generation list. Once you have moved all the shapes you want to that list, click Next at the bottom of the screen to advance to the Configure endpoint screen.
Note
When creating Creating a GraphQL interface from OWL ontologies and SHACL shapes, specifying the interface’s ID is an important part of its configuration. When creating a GraphQL schema shapes one, however, the ID is automatically created from the local part of the IRI identifying the graphql:Schema instance used to define the schema. So, if your graphql:Schema instance has the IRI http://example.com/ns/model/employee/EmpSchema, its interface ID within the repository where it is stored would be “EmpSchema”.
This screen includes an Advanced settings toggle switch that display additional settings. The following shows a complete list of the regular and advanced parameters grouped in the categories used there:
Note
These settings can also be set using the predicates listed under GraphQL schema generation configuration options .
Generic settings
Default String Mode: the default property range when the range is not explicitly defined. Choose from string, langString, or stringOrLangString.
Use GraphQL Unions: whether to
sh:ortogether multiple specified types or to just pick one.Force Interface Types: whether parent types should always be interfaces or split between interface and subclass.
Default Maximum Cardinality: an integer number specifying the maximum cardinality or the string “inf” (the default) to indicate no limit.
Use SHACL Property Labels: whether to use
sh:PropertyShapelabels and descriptions instead ofsh:pathlabels and descriptions.
Data Cleanup
Remove Unknown Ranges: whether to remove properties with unknown ranges.
Clean Invalid InverseOf Relations: whether to remove invalid
sh:inverseOfproperties.Include Deactivated Shapes: whether to include deactivated SHACL shapes in the schema.
Enterprise settings
Read RBAC Rules: whether to read RBAC rules and apply them to the API access. If this is not checked and security is enabled and you do not have a license for extended GraphQL support, the endpoint will not be accessible. (If you do not have a proper license loaded, you would not be able to use the endpoint anyway.)
All of the parameters above have default settings, so if those all look fine to you then you can just click the Next button to continue.
The Configure endpoint screen includes a Create endpoint button. Once you click it, GraphDB will generate an endpoint for each GraphQL schema shape that it found and list them as links to a GraphQL Playground where you can use GraphiQL to generate queries and mutations to execute with your new endpoint. Read more about this at Using your GraphQL endpoints with the GraphiQL Explorer.
Customizing data access¶
In the sample GraphQL Schema Shapes model above, both of its classes were declared as graphql:publicShape shapes. The following list of properties from the datashapes vocabulary includes other options that you can use to control the visibility of different parts of your model in the GraphQL endpoint API.
Note
See GraphQL schema generation configuration options for background on the ontology that defines the so: properties.
graphql:Schema: an instance of this type provides the IRI identifier for the GraphQL Schema Shapes model.graphql:name: when assigned to thegraphql:Schemainstance, this becomes the endpoint name used in Workbench. When assigned to a node shape, it becomes the name of the type generated from that nodeshape in the GraphQL endpoint and will be displayed as that type’s name in GraphiQL. When assigned to a property shape, it becomes the name of the field generated from that property shape and will be displayed as that field’s name in GraphiQL.graphql:publicShape: As shown in the example above, this property of agraphql:Schemainstance identifies which declared SHACL shapes should be part of that instance’s GraphQL shapes model. A public shape can be queried via the GraphQL endpoint without restrictions. If the supertypes of the referenced type of a shape are not added explicitly in the model, the parent properties will be included in the type.graphql:publicClass: This property of agraphql:Schemainstance declares declares which classes will be exposed as types in the GraphQL API. These classes and their subclasses will be included in the GraphQL schema and can be queried without restrictions.graphql:privateShape: This alternative tographql:publicShapeindicates that a shape should not be exposed as part of the GraphQL API being defined. This can be useful when defining multiple APIs to the same dataset. If a relation has one of these types as range then the property will be changed to a range of IRI. To hide the property itself, useso:privateProperty, which is described below.graphql:protectedShape: This alternative tographql:publicShapeindicates that a shape’s type cannot be queried by itself — that is, no queries or mutations can directly read or write instances of this type — but, these operations can be done via relations coming from public types or other protected ones. For example, ifAddressin the example above was a protected shape, it would not be shown in GraphiQL as a top-level type but instances of this type would still be accessible whenEmployeeinstances hadaddressvalues pointing to them.graphql:protectedClass: This property of agraphql:Schemainstance declares that a class will not be exposed as a type in the GraphQL API. This class and its subtypes will be included in the GraphQL schema but cannot be queried directly and can only be accessed via relation.graphql:defaultPrefix: Points at ash:prefixvalue andsh:namespaceIRI value to indicate which namespace should be treated as the default. For most type and field names generated as part of the GraphQL interface, the relevant prefix is prepended with an underscore — for example, ad:givenNameproperty would be shown asd_givenName. This will not be done for the prefix and namespace identified with thegraphql:defaultPrefixproperty. If the prefix named here wasd:along with its corresponding IRI, the example field name would begivenName. This value is also used to initialize the vocabulary IRI for the schema.graphql:isInterfaceordash:abstract: If set to true for a node shape or type, then that node shape or type should become a GraphQL interface.graphql:uriTemplate: Can be used to attach a URI template to node shapes. This provides an alternative to theso:patternpredicate.
so:privateProperty: specifies a list of properties that should be hidden from the GraphQL schema.so:protectedProperty: specifies a list of relations that should not expose the range of the related property. These properties will get a range of IRI as the default.so:publicNamespace: The namespace or namespaces of node shapes that shall be published by the GraphQL schema. This will use the values ofsh:namespaceof the linked prefix declarations. This can be used to import other GraphQL models based on theirgraphql:defaultPrefixdefinition. In the following example, when a GraphQL API is generated fortest:MySchema1it will include the definitions of thetest:MySchema2as it matches thegraphql:publicNamespace/sh:namespacevalue to thetest:MySchema2graphql:defaultPrefix/sh:namespacevalue.@prefix test: <http://example.org/test#> . @prefix test2: <http://example.org/test2#> . @prefix sh: <http://www.w3.org/ns/shacl#> . @prefix graphql: <http://datashapes.org/graphql#> . @prefix owl: <http://www.w3.org/2002/07/owl#> . test:MySchema1 a graphql:Schema ; graphql:defaultPrefix [ sh:prefix "test" ; sh:namespace "http://example.org/test#" ]; graphql:publicNamespace [ sh:namespace "http://example.org/test2#" ]. test:MySchema2 a graphql:Schema ; graphql:defaultPrefix [ sh:prefix "test2" ; sh:namespace "http://example.org/test2#" ]; graphql:publicShape test2:MyShape. test2:MyShape a owl:Class, sh:NodeShape ; sh:property [ sh:path rdfs:label ; sh:datatype xsd:String ; ].
Here is the resulting model shown in YAML syntax:
id: /soml/MySchema1 prefixes: rdfs: http://www.w3.org/2000/01/rdf-schema# test: http://example.org/test# test2: http://example.org/test2# specialPrefixes: vocab_prefix: test vocab_iri: http://example.org/test# objects: test2:MyShape: type: test2:MyShape props: rdfs:label: kind: literal max: inf range: string rdfProp: rdfs:label
Available SHACL constraints¶
The following SHACL constraints are available to specify more details about the type and field data made available with the GraphQL interface:
The so:sparqlTemplate property lets you define SPARQL templates to represent the property path. This has two forms, both demonstrated here:
@prefix so: <http://www.ontotext.com/semantic-object#> .
@prefix graphql: <http://datashapes.org/graphql#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix voc: <http://example.com/voc#> .
voc:MyShape a sh:NodeShape ;
sh:property [
graphql:name "myTemplateProperty1" ;
sh:path [
so:sparqlTemplate "?_subject .. ?_object" ;
so:restrictive true #/ default is false
] ;
sh:class voc:Person ;
] .
voc:MyShape a sh:NodeShape ;
sh:property [
graphql:name "myTemplateProperty2" ;
so:sparqlTemplate "?_subject .. ?_object" ;
sh:datatype xsd:int ;
The full form lets you set the template as restrictive. This prevents the SPARQL generation from wrapping the given property in optional clauses when querying. This forces the results to be filtered based on the template matching. This is mainly used when querying GraphDB connectors and results need to be filtered by the query itself.
Creating a GraphQL interface from OWL ontologies and SHACL shapes¶
Without defining a GraphQL Schema Shapes model, you can still have GraphDB generate a GraphQL API and endpoint using existing RDFS and OWL modeling and SHACL shapes. When doing this, keep the following in mind about the models that you provide as input:
If you have only RDFS and base OWL, then the GraphQL properties are assigned based on domain and range predicates used in the models as well as schema:domainIncludes and schema:rangeIncludes statements.
If you have OWL restrictions, the model will be based on them plus the constructs listed above.
If SHACL statements are included, they will have higher priority then the rest. They will still be read but would only affect the model if the
sh:targetClassdoes not map to the sameowl:Classorrdfs:Class.
To create this style of GraphQL interface, after selecting and then New endpoint, click the OWL ontologies/SHACL shapes radio button. This displays a screen where you set general information about the endpoint:
Endpoint ID: the system ID for the endpoint. This is required and will be used in, for example, HTTP API calls that reference this endpoint. This is the only required field on this page.
Vocabulary prefix: the prefix that corresponds to the vocabulary IRI. This is not added to ordinary properties in the GraphQL schema . For example, if
propis defined aspfx:prop, it will be visualized simply asprop. However, a reserved word such asnamemust be defined aspfx:nameto avoid collision with the predefined property, and will be visualized aspfx_name. The same applies to the reserved wordsidandtype.Endpoint label: a human-readable name for the endpoint.
Endpoint description: A longer description of the endpoint.
A choice of radio buttons at the bottom of the screen lets you designate which of the repository’s graphs to use when generating the GraphQL schema:
Use all graphs: use all the graphs in the repository.
Use SHACL shape graph: use the graph designated for SHACL validation. The default is the
http://rdf4j.org/schema/rdf4j#SHACLShapeGraphnamed graph, but you can assign a different name to the SHACL validation graph when you Enable SHACL validation while Creating and configuring a SHACL repository.Select one or more graphs: this displays the repository’s named graphs so that you can select which of them you would like included to expose in the GraphQL endpoint being created.
Clicking this screen’s Next button takes you to the New endpoint screen.
This screen includes an Advanced settings toggle switch that display additional settings. The following shows a complete list of the regular and advanced parameters grouped in the categories used there:
Note
These settings can also be set using the predicates listed under GraphQL schema generation configuration options .
Generic settings
Default String Mode: the default property range when the range is not explicitly defined. Choose from string, langString, or stringOrLangString.
Use GraphQL Unions: whether to
sh:ortogether multiple specified types or to just pick one.Force Interface Types: whether parent types should always be interfaces or split between interface and subclass.
Default Maximum Cardinality: an integer number specifying the maximum cardinality or the string “inf” (the default) to indicate no limit.
Use SHACL Property Labels: whether to use
sh:PropertyShapelabels and descriptions instead ofsh:pathlabels and descriptions.
Data Cleanup
Remove Unknown Ranges: whether to remove properties with unknown ranges.
Clean Invalid InverseOf Relations: whether to remove invalid
sh:inverseOfproperties.Include Deactivated Shapes: whether to include deactivated SHACL shapes in the schema.
Enterprise settings
Read RBAC Rules: whether to read RBAC rules and apply them to the API access. If this is not checked and security is enabled and you do not have a license for extended GraphQL support, the endpoint will not be accessible. (If you do not have a proper license loaded, you would not be able to use the endpoint anyway.)
All of the parameters above have default settings, so if those all look fine to you then you can just click the Next button to continue.
The next screen includes a Create endpoint button. Once you click it, GraphDB will generate an endpoint and provide a link to a GraphQL Playground where you can use GraphiQL to generate queries and mutations to execute with your new endpoint. Read more about this at Using your GraphQL endpoints with the GraphiQL Explorer.
GraphQL schema generation configuration options¶
In the RDF provided as input to the GraphQL schema generator, the following properties give you additional customization options. These are from the Semantic Object Modeling Language (SOML) ontology, which uses the prefix so: to represent the http://www.ontotext.com/semantic-object/ namespace. You can find this vocabulary at soml-ontology.ttl.
You can set these options for a given GraphQL Schema Shapes model by including a triple like the following in the definition of that model:
ex:myGraphQLSchema so:useUnions true .
Configuration predicate |
Possible values |
Default value |
Description |
|---|---|---|---|
|
|
|
If enabled, the SHACL property labels will have higher priority than the |
|
|
|
Whether the parser schema should honor the |
|
|
|
Whether additional post processing should be done to clean invalid |
|
|
|
Whether the converter should try to use GraphQL unions where possible. This applies when an object property’s range has multiple values or the |
|
1, int number, “inf” or “unbounded” |
“inf” |
The default maximum cardinality setting to use when not defined explicitly. This determines whether all properties are multi- or single-valued by default. |
|
|
|
When enabled, the parent types will always be pure interfaces without concrete superclasses unless explicitly defined as not being interfaces by having the predicates |
|
|
|
When enabled, the invalid ranges of the model will be replaced with IRI. |
|
|
|
Whether the generator should read the RBAC definitions from the model or not. If they are read and the GraphDB license does not include the GraphQL extended capability then the generated endpoint will be restricted. |
Managing GraphQL endpoints¶
Select to display the screen that lists the existing GraphQL endpoints for the currently active repository. The example below shows three endpoints stored with an “employees” repository.
Above the table with the endpoint list the screen has the following:
A Filter by ID or Label field in the upper left lets you set the table to only display rows whose ID or Label values match a string that you enter.
A New endpoint button starts the wizard that leads you through the creation of a new endpoint. See Creating GraphQL endpoints for more on this.
The Import schema definition file button in the upper right imports a schema definition file. These files are typically created by exporting them from another schema with the Export schema definition choice of each table row’s Actions
menu.
The Endpoint Management screen’s table has the following information about each endpoint:
: display a longer description of the endpoint if that was includes with the schema definition.
: display the creation report from when this endpoint was generated. This is displayed in a dialog box that lets you delete the report or download it as JSON.
Id: the ID assigned to the endpoint when it was created. This will be used in, for example, HTTP API calls that reference this endpoint.
Label: a name that you can assign upon creation that is typically more human-readable than the ID.
Default: Whether this is the default endpoint to use when an operation such as an HTTP API call uses an endpoint from this repository without specifying which one. Clicking one of these circles assigns that circle’s endpoint to be the active one, as indicated by the blue filled-in circle.
Active: Whether this endpoint is currently active. Each row includes a toggle button that lets you turn this on or off.
Modified: The last time that the configuration of this row’s endpoint was changed.
Types: The number of types defined in this endpoint’s schema.
Properties: The number of properties defined in this endpoint’s schema.
Actions: Additional actions that you can take with this row’s endpoint:
Export schema definition: Save a YAML schema definition file that can be imported into another endpoint configuration with the Import schema definition file button mentioned above.
Configure endpoint: Display configurable parameters for this endpoint. See Endpoint configuration settings below for details.
Delete endpoint: Remove this endpoint from the repository’s collection.
Endpoint configuration settings¶
When you select Configure endpoint from the Actions menu on an endpoint’s Endpoint Management row, this displays the Configure GraphQL endpoint dialog box. This dialog box includes an Advanced settings toggle that displays additional settings; the following shows a complete list of Configure GraphQL endpoint settings grouped in the categories used there:
GraphQL settings
Enable Type Count Queries: Boolean property that controls whether count queries should be generated for all queryable types in the GraphQL schema. The queries are in the form of
<type>_count : Intwith support for filters. For example, if this is on, anEmployeetype in the schema would include anemployee_countfield that let you count the instances of that type with various options such asdistinct:andincludeInferred:. Disabled by default.Enable Collection Count: Boolean property that controls whether the multi-valued properties should have a companion property that provides counting of the collection properties. The new attributes are in the form of
<relation>_count : Intwith support for filters. Disabled by default.Compact Error Messages: Boolean property that enables more concise messages for certain types of errors. For example, some errors may cause messages for each object of a given type that causes the error; if this parameter is on, only one error message will be returned for each type that caused the error.
Default Fetch Language: Default language spec (for example,
en,en,fr,~,NONE, orANY) to apply when loading values for the name property. If this is not set, all values will be returned. See Using language specifications in your GraphQL queries for examples of language specs.Default Language Validation: Set the default language validation rules to use for mutations of langString or stringOrLangString properties, including language uniqueness.
Default Implicit Language: Determines the implicit language to use when inserting language-tagged strings if none is specified in a mutation.
Include Inferred Data: Whether inferred data in the repository should be available via the endpoint.
Expand owl:sameAs: Whether the endpoint should provide data based on triples inferred from
owl:sameAsrelationships.Default Name Fetch Language: Default language spec to apply when loading values for the GraphQL
nameproperty. The first value matching the specified language in order will be used. See Using language specifications in your GraphQL queries for examples of language specs.Append Default Name Fetch: When a GraphQL
nameproperty is mapped to an RDF property of type langString, which sometimes has multiple values for different languages, this helps to pick one. When this is set to on, the Default Name Fetch Language spec, if any, will be applied automatically for the name properties. See Using language specifications in your GraphQL queries for examples of language specs.
Security settings
Enable Mutations: Whether mutations of data are allowed via the endpoint.
Default User Role: Which RBAC role to use as a default.
Enable GraphQL Explain: Whether to enable requests for explain plans to be generated by the underlying SPARQL query and returned with the GraphQL query results. Add these requests by including
(from: "onto:explain")after an object name in a query, like this:query MyQuery { employee(from: "onto:explain") { familyName } }
Using
(from: "onto:sparql")instead of(from: "onto:explain")will retrieve the generated SPARQL query instead of the explain plan.Expose Model in GraphQL: Includes model configuration details in the GraphQL schema. These will show up as additional information about the schema in GraphQL introspection queries.
Integration settings
SPARQL Federated Services: Allows configuration of SPARQL federated service endpoints for the GraphQL endpoint. Enter this in JSON format with each service name being a key and the service address being the key’s value.
SPARQL Federated Services Priority: Determines the priority of SPARQL federated service endpoint configurations. Controls whether deployment-wide settings or individual endpoint configurations take precedence.
Query Prefix: A prefix to be added to all query names in the GraphQL schema. For example, if this is set to “q1”, a query that might otherwise have been generated as
query empQuery {employee {id}}will be generated asquery q1_empQuery {employee {id}}.Mutation Prefix: Similar to Query Prefix but adds prefixes to mutations.
Using language specifications in your GraphQL queries¶
Several GraphQL schema configuration parameters specify behavior using language specifications. These may be as simple as a single string naming a language like “fr” or they may be more complicated patterns. This section shows some of the possibilities.
Below are some examples of language specifications that return one value or no values. “First” means the first value that matches a condition. If there are several, one is picked at random.
Language Spec |
Returns one value |
|---|---|
|
first value with any language (or no language) |
|
first value with non-empty language, then no language |
|
first English-language value |
|
first English-language value, then a French-language value |
|
first en-CA, then any English “dialect”, then any French “dialect” |
|
first en-CA, then any English “dialect”, then any non-empty language |
|
first en-CA, then any English, then any value |
|
first en-CA, then any English, then any non-empty language, then empty language |
|
first value in English, then a pure string (no language tag) |
|
first pure string (no language tag) |
|
same, but more verbose |
|
first value that has a non-empty language |
|
same |
|
same, but more verbose |
|
first value that is not in French |
|
first value that is not in any French dialect |
|
first value based on the user preferences or empty language |
Examples of language specs that return many values. The language order is irrelevant.
Language Spec |
Returns many values |
|---|---|
(none) |
return all values |
|
same - return all values |
|
same, but more verbose |
|
same, but even more verbose |
|
all English-language values |
|
all English-language or English “dialect” values |
|
all values with language tag |
|
all values without language tag (pure strings) |
|
all English-language or English “dialect” values except American English |
|
all user preferred languages or English-language or English “dialect” |
Note
When the BROWSER keyword is used with ALL, the language weights that come with the Accept-Language
HTTP header are ignored and the order of the results is undetermined.
Examples of invalid language specs:
Language Spec |
Error |
|---|---|
|
You cannot use language exclusion |
|
Language |
|
Language |
|
Language mode |
|
Language |
|
Language |
|
Language |
|
|
Using and managing GraphQL schemas with the GraphDB REST API¶
The GraphDB API section of the GraphDB API Swagger documentation lists two categories of API calls for working with the GraphQL API:
The GraphQL API section shows calls that can list a repository’s current GraphQL endpoints and API calls that send (via both
GETandPOSTHTTP requests) GraphQL queries to default or non-default endpoints.The GraphQL management section shows REST API calls to manage the GraphQL models – for example, to generate, retrieve, edit, and report on them.
As an example, the following curl command uses the “List all active GraphQL endpoints” API call to retrieve information about the two GraphQL endpoints defined for the emp9c repository:
curl http://localhost:7200/rest/repositories/emp9c/graphql/endpoints
The result shows two endpoints in that repository, named EmpSchema” and “inventory”:
[
{
"id": "EmpSchema",
"active": true,
"label": "Employee GraphQL Schema",
"description": null,
"lastModified": "2025-03-18T17:39:10.156Z",
"objectsCount": 3,
"propertiesCount": 7,
"warnings": 0,
"errors": 0,
"default": true
},
{
"id": "inventory",
"active": true,
"label": null,
"description": null,
"lastModified": "2025-03-18T19:24:25.921Z",
"objectsCount": 0,
"propertiesCount": 0,
"warnings": 1,
"errors": 0,
"default": false
}
]
The next curl command does an HTTP POST of the “Query specific GraphQL schema” API call to send an introspection GraphQL query for the names of all the types offered by the GraphQL API:
curl -X POST -H "Content-Type: application/json" \
--data '{ "query": "query { __schema { types { name } } } " }' \
http://localhost:7200/rest/repositories/emp9c/graphql/EmpSchema
The result will be returned as a JSON block.
The GraphDB API Swagger documentation describes further details about the API calls that you can make — for example, parameters to pass and the structure of the expected results.
Role-Based Access Control¶
Having a GraphQL schema, you can control which information is returned or available for modification by a client’s query using the built-in Role-Based Access Control (RBAC). Using RBAC, you can segregate duties within a team and grant the users the precise level of access necessary to perform their work.
The RBAC uses role definitions in the GraphQL schema to define access on a granular level. The role definitions map to Custom user roles in GraphDB. Whenever a client invokes a GraphQL query or mutation, the RBAC mechanism checks the user’s custom roles against the rules defined for those roles in the schema.
RBAC generation is enabled by default. It is controlled by configuration so:readRBACRules.
Warning
The Role-Based Access Control requires a GraphQL license. In case the schema has defined RBAC, but the necessary license is missing, no operations will be executed.
RBAC is applied only to users who are not Admins or Repo managers.
Role Definitions (Objects and Schema)¶
A role definition is a collection of triplets called actions with the format <object>/<property>/<operation>. It lists the object or property that can be read, written (created or updated), or deleted. Roles can be defined as high-level, such as owner or admin, or specific, such as a user with access to a particular property of a particular object.
Role definitions are declared in the GraphQL Schema. RBAC controls across the query and mutation of the objects or properties contained within a particular schema.
If the user does not have an assigned role, a default one will be assigned. Requests with missing role claims (where no role has been included) or roles that are not defined within the RBAC declaration will fall back to the Default role, which will allow all access.
Note
The behavior of the Default role can be redefined. To redefine the Default role, simply add it to the schema:
rbac:
roles:
Default:
description: "Overwriting the Default role, which will allow read access to all users without a role"
notActions: [
"*/*/read"
]
Actions and notActions are explained in further detail below.
Actions and notActions¶
Action permissions specify the data operations that the role is allowed to perform.
If a role has read access to an operation with an object, then users with the corresponding custom role will be able to perform root level query, and query or read these object types within nested queries.
If a role has write access to an operation with an object, then users with the corresponding custom role will be able to perform root level create or update mutation operation, and update these object types within nested queries.
If a role has write access to an operation with an object, then users with the corresponding custom role will be able to perform root level delete mutation operation and delete these object types within nested queries.
The action grammar for is as follows:
{Object Regular Expression}/{Property Regular Expression}/read|write|delete|*
Currently, only * is allowed for {Object Regular Expression} and {Property Regular Expression}. Below you can find some examples of the action grammar:
Actions |
Description |
|
Read, write and delete access to all objects and all properties. |
|
Read (Query) access to all objects and all properties. |
|
Write (Create) access to all objects and all properties. |
|
Delete mutation operation access to all object and all properties. |
|
|
|
Read access to all properties named |
While actions are used to allow access to an operation, notActions are used to specify the data operations that are excluded from the allowed actions. The access granted by a role (effective permissions) is computed by subtracting the notActions from the actions operations.
Warning
notActions take precedence over actions.
The notAction grammar is otherwise the same as the one for actions:
{Object Regular Expression}/{Property Regular Expression}/read|write|delete
notActions defined for an abstract class are overridden by the child class.
For example, the following role definition would allow DroidMgr to perform any type of data operations with all Droid properties, with one exception — the DroidMgr roles would not be allowed to read the Droid.name property:
DroidMgr:
description: "Role that accesses every property of Droid except name"
actions: [
"Droid/*/*"
]
notActions: [
"Droid/name/read"
]
RBAC Filters¶
If you need to fine-tune the role access, you can use filters with the RBAC actions. To add a filter, simply add a fourth section to the action containing the filter you wish to apply:
{Object Regular Expression}/{Property Regular Expression}/read|write|delete|*/(where:{Filter expression})
Filters can be used in all types of actions — read, write, and delete — as well as in mutations. Filters can also be combined — action filters are combined using OR, while notAction filters are combined using AND.
For example, let’s take a look at the following rule:
HumanFromTatooineAdmin:
description: "Can do everything with Tatooine and its residents."
actions: [
'Human/*/*/(where:{homeworld:{name:{EQ: "Tatooine"}}})',
'Planet/*/*/(where:{name: {EQ: "Tatooine"}})'
]
It gives the following permissions:
Delete
humanobjects fromTatooine.Update
humanobjects fromTatooine.Create
humanobjects fromTatooine.Create, update or delete
Tatooineplanet itself.
Thus the following mutations are valid:
Delete and Update, since https://swapi.co/resource/human/4 (Darth Vader) is from Tatooine:
mutation {
delete_Human (where: {ID: "https://swapi.co/resource/human/4"}) {
human {
id
}
}
}
mutation {
update_Human (
objects: {
desc: "From tatooine"
},
where: {ID: "https://swapi.co/resource/human/4"}) {
human {
id
}
}
}
However, you would not be allowed to update human objects that are not from Tatooine. So the following mutation will produce an error:
mutation {
update_Human(
objects: {
desc: "Person from Tatooine"
}
where: {id: {}}
) {
human {
id
}
}
}
{
"message": "ERROR: The UPDATE has been prevented as the selected objects of type 'Human' failed to match the constraints '(where: [{homeworld: [{name: [{EQ: \"Tatooine\"}]}]}])'",
"locations": [
{
"line": 3,
"column": 17
}
]
}
The reason is that the applied filter (where: {id: {}}) will effectively select all human objects from the database, and not all of them are from Tatooine. So instead of updating only the human properties for which you have access, the whole mutation gets blocked and nothing gets updated.