GraphQL Query Tutorial

The following sections provide examples of Star Wars GraphQL queries and responses. If you have started the services following the Quick Start guide, you can also try the queries out and modify them as you see fit.

All examples in this section are based on the Star Wars dataset.

Retrieve Objects

GraphQL queries can fetch single or multiple object types.

Retrieve a List of Objects

All we have to do to fetch multiple object types using the Semantic Objects is to define a valid nested GraphQL query.

Let’s say that we need some basic information about all the characters in the Star Wars saga. We need to:

  • define a name for our query
query allCharacters {}
  • set the type of objects (character) and properties (id, name, gender, birthYear, height) that we want to retrieve.
 query allCharacters {
    character {
        id
        name
        gender
        birthYear
        height
    }
}

And that’s it! We have our first query that can retrieve all the characters within the Star Wars dataset. You can edit the query directly in the integrated GraphiQL editor.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query allCharacters { character { id name gender birthYear height } }

Using the same approach, we can define as many queries as we need. The next example fetches all Star Wars films including some of their properties.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query allFilms { film { name episodeId role { roleType person { name } } releaseDate } }

Retrieve a Single Object

To retrieve a single object, we can filter a list of objects using a known, unique property value.

For example, let’s say we want to retrieve information about a single Star Wars character Luke Skywalker that has a unique ID property which equals https://swapi.co/resource/human/1.

We can do this by altering the allCharacters query (above), by adding a ID filter upon the set of all characters:

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query character { character(ID: "https://swapi.co/resource/human/1") { id name gender birthYear height } }

Retrieve Nested Objects

Now let’s fetch objects and their related objects using single or multi-valued object properties that are defined in the SOML schema. The relationships can be defined using objects single value properties (one-to-one) or multi-valued properties (one-to-many).

These nested object queries retrieve data for an object type along with data from nested or related object types.

The previous example only retrieved scalar information for the Luke Skywalker object. We will extend the example to use nested object properties as well as scalar properties.

The SOML schema defines several nested object relationships using object ranges. For example, the film object property has a Film object type for its range.

Character:
  kind: abstract
  typeProp: "rdf:type"
  type: ["voc:Character"]
  props:
    film: {descr: "Star Wars films appeared in", max: inf, range: Film}
    homeworld: {label: "Characters homeworld(planet)", range: Planet}
    starship: {label: "Characters starship(s)", max: inf, range: Starship}
    vehicle: {label: "Characters vehicles(s)", max: inf, range: Vehicle}
    species: {label: "Characters species", range: Species, rdfProp: "rdf:type", rangeCheck: true}

We will use the film relationship and will fetch the names of all films with the Luke Skywalker character.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query lukeSkywalkerFilms { character(ID: "https://swapi.co/resource/human/1") { id name gender birthYear height film{ name } } }

We can go even deeper and extract all the starships that appear in the films that Luke Skywalker appeared in.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query starshipsInLukeSkywalkerFilms { character(ID: "https://swapi.co/resource/human/1") { id name gender birthYear height film { name starship { name } } } }

Ordered Object List

An object list can be ordered by using an orderBy input argument with an ascending (ASC) or descending (DESC) order.

Note

The order can be applied to objects and multi-valued object properties based on single value or multilingual string based scalars. It can be applied to multi-valued scalars as well.

Now let’s sort a list of character objects by height.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query charactersOrderedByHeight { character(orderBy: {height: DESC}) { id name height } }

We can order nested object properties as well. In the next example, we order all the films that Luke Skywalker appeared in by the film’s name in ascending order.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query lukeSkywalkerFilmsOrderedByName { character(ID: "https://swapi.co/resource/human/1") { id name gender birthYear height film (orderBy: {name: ASC}){ name } } }

It is also possible to order using two or more properties.

<object> (orderBy: {<property1>: <ASC/DESC>, <property2>: <ASC/DESC>})   {<properties>}

In the next example, we order all the films that Luke Skywalker appeared in by the films name (in ascending order). We also, order all the starships that appeared in each film by their maxAtmospheringSpeed (in descending order). If the starships have an equal maxAtmospheringSpeed, then the starships are additionally ordered by cargoCapacity in descending order.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query starshipsInLukeSkywalkerFilmsOrderedBySpeedAndCapacity { character(ID: "https://swapi.co/resource/human/1") { id name gender birthYear height film (orderBy: {name: ASC}){ name starship (orderBy: {maxAtmospheringSpeed: DESC, cargoCapacity: DESC}){ name maxAtmospheringSpeed cargoCapacity } } } }

Another possibility is to order an object list using nested object properties.

<object> (orderBy: {<object_property1>: {<property1>:<ASC/DESC>}})   {<properties> <object_property1>{<property1>}}

For example, let’s order a list of character objects by the character’s species name in ascending order.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query charactersOrderedBySpeciesName { character (orderBy: {species: {name:ASC}}) { id name gender birthYear height species {name} } }

In Semantic Objects 4.1, we can order a list of objects represented by an abstract type using the specific properties from the one or more sub types using the following construct:

<abstract_object> (orderBy: {
                    <common_property>: <ASC/DESC>,
                    _ifSubType1: {<object_property1>: {<property1>: <ASC/DESC>}},
                    _ifSubType2: {<property2>: <ASC/DESC>}
                   }) {
  <common_property>
  ... on SubType1 { <object_property1> { <property1> } }
  ... on SubType2 { <property2> }
}

In this case, the objects will be first grouped into a bucket, that consists of objects that have a value for the first property for sorting and will be ordered by the given direction. The remaining objects, that does not have the first property, will be grouped by the second property filter, if applicable, and placed into a bucket. The second bucket will be ordered by the second property for the specified sort direction. The remaining objects will be added as is to the end of the results or ordered by the next criteria again, if present. This is done until all sort properties are exhausted.

We can also order a multi-value scalar property. The species object definition includes several multi-value scalar properties. For example, skinColor has a max cardinality defined as inf. This indicates that the skinColor property can have infinite (multiple) values, e.g., “white”, “brown”, “black”, “beige”, etc.

Species:
   type: ["voc:Species"]
   typeProp: "rdf:type"
   props:
     skinColor: {descr: "Species skin colour", max: inf}
     hairColor: {descr: "Species hair colour", max: inf}
     eyeColor: {descr: "Species eye colour", max: inf}
       ...

Let’s order the species skin color property values:

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query characterOrderedBySpeciesSkinColor { character(ID: "https://swapi.co/resource/human/1") { id name gender birthYear height species{ name skinColor(orderBy: ASC) } } }

LangString Ordering

As discussed in the Ordered Object List section, we can apply orderBy in two distinct cases:

  • Order the values of the multi-valued scalar properties
  • Order object array by field: use a single-value field to order its multi-valued parent object

The same two cases apply for langString fields, but such fields are treated as single-valued or multi-valued dynamically, depending on the effective language pattern.

Ordering of LangString Values

When fetching a multi-valued string or langString field, you can use orderBy, limit, and offset to order the values, but only if the language specification in effect is using ALL. Otherwise, an error will be returned.

Here is an example use of the orderBy to return and sort the English and French language values in ascending order:

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query humanDescriptions { human(where: {desc: {}}) { id name desc(lang: "ALL:en~,fr~", orderBy: ASC) { value lang } } }

Other examples of ordering a multi-valued literal properties:

Query Result
{human {desc(lang: “ALL”, orderBy: ASC) {value}}} All values in ascending alphabetical order
{human (lang: “ALL”) {desc(orderBy: ASC) {value}}} Same: ALL is inherited from the higher level
{human {desc(orderBy: ASC) {value}}} Same unless changed in the schema: ALL is the global default
{human {desc(lang: “ALL:en”, orderBy: ASC) {value}}} All English-language values in ascending alphabetical order
{human {desc(lang: “ALL:en~”,orderBy: ASC) {value}}} All values in English (or “dialect”) in ascending alphabetical order
{human {desc(lang: “ALL:NONE”,orderBy: ASC) {value}}} All values without language tag in ascending alphabetical order
{human {desc(lang: “en”, orderBy: ASC) {value}}} Error: orderBy cannot be used without ALL

Ordering by Single LangString Value

When fetching a multi-valued object field, you can order by a string or langString field if the field is single-valued, or if the language specification in effect does not contain ALL.

Note that the langString fields have different arguments when ordering by them. The format is as follows:

<object>(orderBy : {<langStringProperty>: {dir: <ASC/DESC>, lang: <filterPattern>}}) {
  <langStringProperty> {
    value
    lang
  }
}

The ordering could be ASC, which is the default if not specified, or could be DESC in Unicode collation order ignoring any language tags.

Due to technical limitations, only values matching the first positive language tag are used for ordering.

If an object does not have a matching value, it comes last for both ASC and DESC directions. There must be a single matching value, otherwise the result of ordering is indeterminate.

It is recommended, but not required, that the ordering field has a UNIQ constraint for that language tag.

Let’s illustrate this with an example:

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query humanDescriptions { human(where: {desc: {}}, orderBy: {desc: {dir: DESC, lang: "en"}}) { id name desc { value lang } } }

Other examples of ordering by langString properties, where desc is a multi-valued langString, label a single-valued langString:

Query Result
{character(orderBy: {desc: {lang: “en”, dir: ASC}}) {desc(lang: “en”) {value}}} Order alphabetically by en language, there must be only one such value, objects with no matching value come first
{character(orderBy:{desc: {lang: “en”}}) {desc(lang: “en”) {value}}} Same: the default dir is ASC
{character(lang: “en”, orderBy: {desc: {}}) {desc{value}}} Same: lang spec inherited from higher level, default dir is ASC
{character(orderBy: {desc: {}}) {desc{value}}} Same, if the default fetch specification is lang: "en"
{character(lang: “en”, orderBy: {desc: {dir: DESC}}) {desc{value}}} Reverse alphabetical order by en desc, objects with no matching value come last
{character(orderBy: {label: ASC}) {label{value}}} Order alphabetically; no language spec needed or allowed for single-valued langString
{character(orderBy: {desc: {lang: “en~”}}) {desc(lang: “en~”) {value}}} Order alphabetically by en~ desc, there must be only one such, objects with no matching value come first
{character(orderBy: {desc: {lang: “ALL”}}) {desc{value}}} Error: ALL is not allowed for ordering
{character(orderBy: {desc: {lang: “ANY”}}) {desc(lang: “ANY”) {value}}} Error: ANY does not specify a concrete lang to order by
{character(orderBy: {desc: {lang: “-fr”}}) {desc(lang: “ANY”) {value}}} Error: -fr does not specify a concrete lang to order by
{character(lang: “fr,en”, orderBy: {desc: {}}) {desc{value}}} Order alphabetically by fr desc, there must be only one such, objects with no matching value come first, return fr or en descriptions
{character(lang: “BROWSER”, orderBy: {desc: {}}) {desc{value}}} Assume the HTTP Accept-Language header has the value ‘fr;q=0.5, en;q=1.0’. This will result in ‘en~,fr~’ as the effective language order pattern. Order alphabetically by en desc, there must be only one such, objects with no matching value come first, return en or fr descriptions

Paginated List of Objects

You can paginate an Object list by using LIMIT and OFFSET input arguments.

LIMIT specifies the number of objects to retrieve per page. OFFSET determines which page slice to retrieve.

Pagination and offsets can be applied to multi-valued object properties.

Note

Pagination and offsets can be applied to multi-valued object properties as well as to multi-value scalars.

The following are examples of different pagination queries.

Let’s restrict the list of films to only return the first page of results (No OFFSET argument), where a page of results is LIMIT-ed to only include two films.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query starshipsInTwoLukeSkywalkerFilms { character(ID: "https://swapi.co/resource/human/1") { id name gender birthYear height film (orderBy: {name: ASC}, limit: 2 ){ name starship (orderBy: {maxAtmospheringSpeed: DESC, cargoCapacity: DESC}){ name maxAtmospheringSpeed cargoCapacity } } } }

To retrieve the second page of results, we need to set an OFFSET to two skips to the second page.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query starshipsInTwoLukeSkywalkerSecondPageFilms { character(ID: "https://swapi.co/resource/human/1") { id name gender birthYear height film (orderBy: {name: ASC}, limit: 2, offset: 2 ){ name starship (orderBy: {maxAtmospheringSpeed: DESC, cargoCapacity: DESC}){ name maxAtmospheringSpeed cargoCapacity } } } }

Now let’s LIMIT the list of starships to include only two results. Again the OFFSET is not defined (the first page of results).

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query twoStarshipsInTowLukeSkywalkerFilms { character(ID: "https://swapi.co/resource/human/1") { id name gender birthYear height film (orderBy: {name: ASC}, limit: 2 ){ name starship (orderBy: {maxAtmospheringSpeed: DESC, cargoCapacity: DESC}, limit: 2){ name maxAtmospheringSpeed cargoCapacity } } } }

We can also use an OFFSET argument on an object list without specifying a LIMIT argument. This allows you to retrieve all results from the OFFSET until the end of the result set.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query allExceptTwoStarshipsInLukeSkywalkerFilms { character(ID: "https://swapi.co/resource/human/1") { id name gender birthYear height film (orderBy: {name: ASC}){ name starship (orderBy: {maxAtmospheringSpeed: DESC, cargoCapacity: DESC}, offset: 2){ name maxAtmospheringSpeed cargoCapacity } } } }

Filtering Object Lists

You can use where: arguments on object lists to filter lists. A where: argument can use property values and nested objects property values within filter expressions.

For top-level queries and multi-valued properties, you can use a where parameter that expresses a search/filter condition in a structured way, using field names (including nested properties), comparison operators (e.g., LT), and Boolean operators (e.g., OR).

It is possible to combine GraphQL query filters within the same where: argument by using the default `AND connective and explicit connectives such as AND:, OR:, EXISTS:.

Comparison Operators

Comparison operators come in pairs:

  • EQ:NEQ: - equality/inequality. Should be used for single values filter expressions.
<object> (where: {<property>: {EQ:<value>}})   {<properties>}

The following query will filter the list of characters to only include those that have the male gender type.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query allMaleCharacters { character (where: {gender: {EQ:"male"}}) { id name gender birthYear height } }
  • IN:NIN: - inside/outside of an array of values (put them in square brackets).
<object> (where: {<property>: {IN:[<value1, value2>]}}) {<properties>}
<object> (where: {<property>: {IN:<value>}})   {<properties>}

Hint

Please note that SPARQL logic is 3-valued: true, false, and undef (in case the input field is missing), so it is possible for both of these to be unsatisfied:

<object> (where: {<property>: {IN:[3]}}) {<properties>} # looks for a value equal to 3
<object> (where: {<property>: {NIN:3}})   {<properties>} # looks for a value different from 3

The following query will filter the list of characters to include only those that have a birthYear IN 19BBY.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query allCharactersBornIn19BBY { character (where: {birthYear: {IN:"19BBY"}}) { id name gender birthYear height } }
  • LT:GTE and LTE:GT: - less-than/greater-than-or-equal and less-than-or-equal/greater-than. Comparison of numbers, strings, or IRIs.

The following GraphQL query will filter the list of Character objects so that it does not include any characters who have height greater than 2 meters.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query allCharactersTallerThan200 { character (where: {height: {GT: 200}}) { id name gender birthYear height } }
  • RE:NRE and IRE:NIRE: - regular expression match/mismatch. The I variants make case-insensitive comparisons using Unicode alphabet collation.

Warning

Regex comparison is slow, so you should only use it on small result sets.

The following query will filter the list of characters to only include those with sky in their name.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query allCharactersWithNameContainingSky { character (where: {name: {IRE: "sky"}}) { id name gender birthYear height } }
  • ID: - access an object or object property by IRI (id).
<object> (ID:"<value>") {<properties>}
<object> (ID:["<value1>",""<value1>""]) {<properties>}
<object> (where: {<object_property>: {ID:"<value>"}}) {<properties>}

Characters starring in a A New Hope film.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query allCharactersInANewHope { character (where: {film: {ID: "https://swapi.co/resource/film/1"}}) { id name gender birthYear height film { name } } }

Logical Connectives

You can also use the following logical connectives:

  • AND (conjunction) is implicit between clauses in the same input object

    To compare two properties of the same object, put them together.

    <object> (where: {<property1>: {EQ:"<value1>"}, <property2>: {IRE:"<value2>"}}) {<properties>}
    

    Filter the list of characters to only include those with a height less than 100 and a mass greater than or equal to 45.0. (note: commas are optional in GraphQL)

    Loading...
    https://swapi-platform.ontotext.com/graphql
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
    true
    query characterHeightMassFilter { character(where: {height: {LT: 100}, mass: {GTE: 45.0}}) { id name gender birthYear height mass } }

    To apply two comparisons to one property (e.g., a range check), put them together.

    <object> (where: {<property1>: {GTE:"<value1>", LT:"<value2>"}) {<properties>}
    

    Filter the list of characters to only include those with a height greater than 150 and less than 165.

    Loading...
    https://swapi-platform.ontotext.com/graphql
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
    true
    query characterHeightBetween { character(where: {height: {GT: 150, LT: 165}}) { id name gender birthYear height } }

    AND is an explicit conjunction: you will need to use it in two cases:

    1. To check two different instances of the same property.
    <object> (where: {AND: [{<object_property1>: {<property2>: {EQ:<value1>}}},
                            {<object_property1>: {<property2>: {EQ:<value2>}}}]}) {<properties>}
    

    Filter the list of characters to only include those that have appeared in films with episodeId 1 AND episodeId 5.

    Loading...
    https://swapi-platform.ontotext.com/graphql
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
    true
    query commonCharactersInFilms { character (where: {AND: [{film: {episodeId: {EQ: 1}}}, {film: {episodeId: {EQ: 5}}}]}){ id name gender birthYear height film { episodeId } } }

    NOTE: You cannot write this query using IN because that would look for all characters starred in the selected episodes.

    <object> (where: {<object_property1>: {<property2>: {IN: [<value1>, <value2>]}}}) {<properties>}
    
    Loading...
    https://swapi-platform.ontotext.com/graphql
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
    true
    query allCharactersInFilms { character (where: {film: {episodeId: {IN: [1,5]}}}){ id name gender birthYear height } }
  • OR takes an array of clauses and applies a disjunction.

    <object> (where: {OR: [{<property1>: {IRE: <value1>}},
                           {<property2>: {IRE: <value2>}}]}) {<properties>}
    

    Filter the list of characters with name Skywalker or eyeColor green:

    Loading...
    https://swapi-platform.ontotext.com/graphql
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
    true
    query charactersWithGreenEyesOrNameSkywalker { character (where: {OR: [{name: {IRE: "Skywalker"}}, {eyeColor: {IRE: "green"}}]}) { id name eyeColor birthYear height } }

    NOTE: If you need to check for one of several values in the same field, it is easier to use RE with | (for text comparison) or IN (for fixed values).

    <object> (where: {<property>: {IRE: "<value1>|<value2>"}}) {<properties>}
    

    Filter the list of characters to only include those with a name property Anakin or Luke in the name:

    Loading...
    https://swapi-platform.ontotext.com/graphql
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
    true
    query charactersWithAnakinOrLukeInName { character (where: {name: {IRE: "Anakin|Luke"}}){ id name eyeColor birthYear height } }

    NOTE: You can use OR at the operator level if you need a disjunction of two comparisons on the same field.

    <object> (where: {<property>: {OR: [{LT: <value1>} {GT: value2}]}}) {<properties>}
    

    Look for characters with height outside the range 100..200.

    Loading...
    https://swapi-platform.ontotext.com/graphql
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
    true
    query characterHeightBetween { character(where: {height: {OR: [{LT: 100}, {GT: 200}]}}) { id name gender birthYear height } }
  • NOT negates a clause. Most of the time you will not need it because you can use negation at the operator level.

    Loading...
    https://swapi-platform.ontotext.com/graphql
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
    true
    query notMaleCharacters { character (where: {NOT: {gender: {IRE: "male"}}}){ id name eyeColor birthYear height } }
  • exists is implicit when checking properties and sub-properties (one value is enough to satisfy the condition).

    <object> (where: {<property>: {}}) {<properties>}
    

    Look for characters with at least one starship and vehicle.

    Loading...
    https://swapi-platform.ontotext.com/graphql
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
    true
    query charactersWithStarshipAndVehicle { character (where: {starship: {}, vehicle: {}}){ id name starship (limit: 1) {name} vehicle (limit: 1) {name} } }
  • ALL is applicable to multi-valued properties and checks that all values satisfy the condition.

    <object> (where: {All: {<object_property>: {<property>: {GTE: <value>}}}}) {<properties>}
    

    Find characters all of whose starships have maxAtmospheringSpeed higher than 1000.

    Loading...
    https://swapi-platform.ontotext.com/graphql
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
    true
    query charactersWithFastStarshipOrMissing { character (where: {ALL: {starship: {maxAtmospheringSpeed: {GTE: 1000}}}}){ id name starship (limit: 1) {maxAtmospheringSpeed} } }
  • Please note that characters without any starship will also be returned by the above query (a vacuous truth), so you may want to add an existence check:

    <object> (where: {All: {<object_property1>: {<property2>: {GTE: <value>}}}
                            <object_property1>: {<property2>: {GTE: <value>}}}) {<properties>}
    
    Loading...
    https://swapi-platform.ontotext.com/graphql
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
    true
    query charactersWithFastStarship { character (where: {ALL: {starship: {maxAtmospheringSpeed: {GT: 1000}}} starship: {maxAtmospheringSpeed: {GT: 1000}}}){ id name starship (limit: 1) {maxAtmospheringSpeed} } }
  • ALL_EXISTS is applicable to multi-valued properties and checks both ALL and exists.

    <object> (where: {ALL_EXISTS: {<object_property>: {<property>: {GTE: <value>}}}}) {<properties>}
    

    The query below filters the list of characters that have starship with only tall pilots (over 180cm) and have at least one such pilot, and returns all their pilots:

    Loading...
    https://swapi-platform.ontotext.com/graphql
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
    true
    query charactersWithStarshipAnaHeightPilots { character (where: {starship: {ALL_EXISTS: {pilot: {height: {GTE:180}}}}}){ id name starship { pilot{ height } } } }

Type Selectors

Version 3.1 of the Semantic Objects introduces a special type selector that acts as a shortcut for type checking as well as provides access to specific type properties when we filter properties with interface range.

The type selector has the form _ifType where Type will be any concrete sub-type for the current interface.

Let’s demonstrate this with an example. In the Star Wars model, we have an interface Character that has many sub-types. Some of them has additional properties that are not present in the parent:

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query planetHumanResidentsWithFriendsOrDroidsWithPrimaryFunctionOrWookiee{ planet(where: {resident: { _ifHuman: {friend: {}}, _ifDroid: {primaryFunction: {}}, _ifWookiee: {}} } ) { name resident { name ... on Human { friend { name } } ... on Droid { primaryFunction } } } }

If we run the example, we would get:

  • All Humans that have any friends
  • All Droids with set primary function
  • All Wookiees

As we can see, the type selector allows accessing concrete properties for the type, as well as filtering the objects from the same type. As the sub-types are disjoint and we combine multiple type selectors, they all are grouped with implicit OR along with any common filters that apply for all of them.

Note

Multiple type selectors are grouped with implicit OR along with any common filters that apply for all of them.

Filtering Literal Values

Standardized language tags are used in HTML, XML, RDF, and various other web standards. They reuse ISO 639 2-letter and 3-letter language codes, and add extra codes for scripts, regions, and other traits (e.g., “dialects”). The format and handling of language tags is specified in the Best Current Practice 47 (BCP47) Tags for Identifying Languages, IETF Network Working Group, Sep 2009.

Literal values can be filtered using the filter syntax described in the section Filtering Object Lists, while literal language has a different syntax that will be covered in the current section.

We consider the following features for various operations:

  • Fetch the values of a field. This includes restriction of the returned languages, setting a preference order, obtaining the first value according to this order, or all matching values.

    For more information, see the Language Fetching tutorial.

  • Filter by the values of a field so that the parent object has values and/or does not have values with specified languages.

    For more information, see the Language Filtering tutorial.

  • Validate values during create/update (mutation) in order to restrict certain languages or ensure uniqueness per language.

    For more information, see the Literal Properties Validation tutorial.

  • Implicit lang: allows to omit the lang tag on insert (mutation).

    For more information, see the tutorials for Creating and Updating Literal Properties.

Language Fetching

The Ontotext Semantic Objects use a specially formatted language string to specify language tags and a preference order for fetching values.

Language elements:

  • lang: exact language match, e.g., en or en-US
  • lang~: language and its “dialects”, i.e., prefix match at the end of a language tag component, for example en~
  • ~: match any non-empty language, i.e., values with rdf:langString type
  • NONE: match values without language tag, i.e., values with xsd:string type
  • ANY: match any language tag, including empty language. Note that this is nearly the same but not equivalent to ~,NONE because that prefers non-empty language first.
  • BROWSER: match language tags passed via the HTTP Accept-Language header. The keyword could be used for fetching and ordering the results. For more information, see the HTTP Accept-Language section.

Exclusions: these discard values with the indicated language:

  • -lang: exclude this language, e.g., -en or -en-US
  • -lang~: exclude this language and any of its “dialects”, e.g., -en~
  • -~: exclude all non-empty languages so it will match values without a language tag
  • -NONE: exclude values without a language tag
  • -ANY is not allowed because it would forbid all values
  • -BROWSER is not allowed

A sequence of elements can also be specified:

  • By default, there are no restrictions on lang, so ALL values are returned.
  • If you specify lang, then only the first value with matching language is returned.
    • Use lang: "ANY" to return a single value, regardless of its language (or whether it has a language at all).
  • Use ALL as first element (with trailing colon :) to return all values with matching languages (e.g., ALL:en,fr should return all values in English and French). If you use this, the order of languages does not matter, and you should not have generic tags that subsume more specific tags (e.g., ALL:en-GB,en-GB~ should not appear).
    • If you use ALL:ANY, then do not use any other language.
  • lang1,lang2,lang3: comma-separated sequence of languages in preference order.
    • You should list more specific tags earlier (e.g., en-GB,en-GB~ or en,en~), else they will have no effect.
    • There should be no duplicates.
  • -lang1,-lang2,-lang3: comma-separated set of exclusions. All are checked, so their order does not matter (and they are customarily specified last). Each exclusion should be less general than any specified language, or it will prevent the language from having an effect. For example, en-GB,en,-en~ makes no sense because the exclusion kills the two preceding languages.
  • BROWSER: the Accept-Language header (see HTTP Accept-Language) is parsed, ordered by specificity, then by q value, converted to lang~ ranges, and inserted instead of the BROWSER keyword.
    • The lang spec is validated as described above (duplicates, lang subsumption and exclusions) before the BROWSER element is replaced, because the Accept-Language header is under user control, not under SOML designer’s control.
    • If the request does not have such header or the value of the header is invalid then the BROWSER keyword is ignored. In this case the following behavior could be expected:
      • lang: "ALL:BROWSER" will have the same effect as lang: "ALL" and will fetch all possible values
      • lang: "BROWSER" will have the same effect as lang: "~" and will fetch the first found language
      • orderBy: {desc: {lang: "BROWSER"}} will have undetermined order result

In order to use any of the above to filter the returned literal values, the fetch spec needs to be used on a lang argument for the given property like in the example below. It returns all characters and a single description in German, or, if no German language description is present, in English.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query charactersWithGermanDescription { character(where: {desc: {}}) { name desc(lang: "de,en") { value lang } } }

Here are some examples of language specs that return one value (or no values). “First” means the first value that matches a condition. In case there are several, one is picked at random.

Language Spec Returns one value
ANY first value with any language (or no language)
~,NONE first value with non-empty language, then no language
en first English-language value
en,fr first English-language value, then a French-language value
en-CA,en~,fr~ first en-CA, then any English “dialect”, then any French “dialect”
en-CA,en~,~ first en-CA, then any English “dialect”, then any non-empty language
en-CA,en~,ANY first en-CA, then any English, then any value
en-CA,en~,~,NONE first en-CA, then any English, then any non-empty language, then empty language
en,NONE first value in English, then a pure string (no language tag)
NONE first pure string (no language tag)
NONE,-~ same, but more verbose
~ first value that has a non-empty language
-NONE same
~,-NONE same, but more verbose
-fr first value that is not in French
-fr~ first value that is not in any French dialect
BROWSER,NONE 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
null same - return all values
ALL same, but more verbose
ALL:ANY same, but even more verbose
ALL:en all English-language values
ALL:en~ all English-language or English “dialect” values
ALL:~ all values with language tag
ALL:NONE all values without language tag (pure strings)
ALL:en~,-en-US all English-language or English “dialect” values except American English
ALL:BROWSER,en~ all user preferred languages or English-language or English “dialect”

Note

When 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
-ANY You cannot use language exclusion -ANY because that forbids all values
ALL:ANY,en Language en is subsumed by ANY so it has no effect in ALL matching mode
ALL:en,en~ Language en is subsumed by en~ so it has no effect in ALL matching mode
en,ALL,fr Language mode ALL is allowed only in first position
en~,en-GB Language en-GB is more specific than en~ but comes later in the list so it has no effect
en~,en-GB~ Language en-GB~ is more specific than en~ but comes later in the list so it has no effect
en,fr,bg,en Language en is specified more than once
en-GB,en,-en~
  • Language exclusion -en~ is more general than language en-GB so the language has no effect
  • Language exclusion -en~ is more general than language en so the language has no effect

HTTP Accept-Language

The HTTP protocol uses an Accept-Language header defined in RFC 2616 Section 14.4 and RFC 3282.

It is based on RFC 4647 and allows the HTTP client (i.e., browser) to:

  • Specify languages acceptable to the user
  • Use “basic lang range” (prefix) matching
  • Match the most specific (longest) range first
  • Use wildcard (*) to match any non-empty lang tag
  • Specify lang precedence by using quality values (q=); the default is 1.0.

Below are some examples and their interpretation:

Accept-Language Interpretation: lang (quality)
da, en-GB;q=0.8, en;q=0.7 Danish (1.0), British English (0.8), other English (0.7)
bg;q=0.1, en-GB;q=0.9, en;q=1.0 British English (0.9), other English (1.0), Bulgarian (0.1)
*;q=0.1, en;q=1.0 Any English (1.0), any other (0.1)
*;q=1.0, en;q=0.1 Any English (0.1), any other (1.0)
*;q=1.0 or just * Any language (1.0)
(no value/missing header) Ignored

In these interpretations, lang ranges are first ordered by specificity, then by quality value.

Please note that examples 2 and 4 do not make a lot of sense since they give more preference to a less specific lang range:

  • Example 2 says “prefer any English to British English” but any does include British English.
  • Example 4 says “prefer any language to English” but any does include English.

In order to access the HTTP header value, the BROWSER keyword must be used.

The header value, if present, is parsed, ordered by specificity, then by q value, converted to lang~ ranges, and inserted instead of the BROWSER keyword.

  • The language spec is validated as described in the previous Language Fetching section (duplicates, lang subsumption, and exclusions) before the BROWSER element is replaced, because the Accept-Language header is controlled by the user and not by the designer of the SOML.
  • If the request does not have such a header or the value of the header is invalid, then the BROWSER keyword is ignored. In this case, the following behavior can be expected:
    • lang: "ALL:BROWSER" will have the same effect as lang: "ALL" and will fetch all possible values.
    • lang: "BROWSER" will have the same effect as lang: "~" and will fetch the first found language.
    • orderBy: {desc: {lang: "BROWSER"}} will have undetermined order result, as for the ordering functionality to work properly, it needs a single value to be selected (preferably in the same language). To minimize the impact of the missing header, add a default to your sort argument, such as orderBy: {desc: {lang: "BROWSER,en"}}.

The following example demonstrates the use of the BROWSER keyword and the HTTP Accept-Language header.

Consider the following SOML schema:

objects:
  skos:Concept:
    props:
      skos:prefLabel:  {max: inf, range: stringOrLangString}
      skos:definition: {max: inf, range: stringOrLangString}

Assume the following data:

<https://nomenclature.info/nom/5313>
  a skos:Concept;
  skos:prefLabel
    "Two-Handed Crosscut Saw"@en,
    "Godendard"@fr-CA,
    "Passe-partout"@fr;
  skos:definition
    "A tool consisting of a stationary, wide, heavy, serrated blade..."@en,
    "Outil composé d'une longue lame dentelée à dos convexe..."@fr.

You can use it to fetch a concept with values for its multi-lingual properties based on the Accept-Language HTTP header with the following query:

query {
  skos_Concept(ID:"https://nomenclature.info/nom/5313") {
    skos_prefLabel (lang:"BROWSER,en") {value lang}
    skos_definition(lang:"ALL:BROWSER") {value lang}
  }
}

It will return:

  • skos:prefLabel - the first value that matches the header value or English value
  • skos:definition - all values matching the header value

Let’s assume the BROWSER Accept-Language is set to "fr, fr-CA". This will effectively set the query lang argument to:

query {
  skos_Concept(ID:"https://nomenclature.info/nom/5313") {
    skos_prefLabel (lang:"fr-CA~,fr~,en") {value lang}
    skos_definition(lang:"ALL:fr~") {value lang}
  }
}

Note that for the skos_definition fetching language pattern the fr-CA~ is ignored, as it is included in the fr~ spec.

Then the following response is returned:

{
  "data": [{
    "skos_Concept": {
      "skos_prefLabel": [
        {"value": "Godendard", "lang": "fr-CA"}
      ],
      "skos_definition": [
        {"value": "Outil composé d'une longue lame dentelée à dos convexe...", "lang": "fr"}
      ]
    }
  }]
}

Now let’s assume the HTTP header Accept-Language is missing. The following response will be returned:

{
  "data": [{
    "skos_Concept": {
      "skos_prefLabel": [
        {"value": "Two-Handed Crosscut Saw", "lang": "en"},
      ],
      "skos_definition": [
        {"value": "A tool consisting of a stationary, wide, heavy, serrated blade...", "lang": "en"},
        {"value": "Outil composé d'une longue lame dentelée à dos convexe...",         "lang": "fr"}
      ]
    }
  }]
}

If the lang pattern with``BROWSER`` is applicable for ordering, like in the example below, only the first value of the pattern will take effect.

query {
  skos_Concept(lang: "BROWSER,en", orderBy: {skos_prefLabel: {dir: DESC}}) {
    skos_prefLabel {value lang}
    skos_definition(lang:"ALL:BROWSER") {value lang}
  }
}

Let’s assume the BROWSER Accept-Language is set to "fr, fr-CA" again. This will set the effective query lang arguments as in the example below.

query {
  skos_Concept(orderBy: {skos_prefLabel: {lang: "fr-CA~", dir: DESC}}) {
    skos_prefLabel(lang: "fr-CA~,fr~,en") {value lang}
    skos_definition(lang:"ALL:fr~") {value lang}
  }
}

For more information about result sorting, see the Ordered Object List section.

Note

When designing a SOML and language fetching, consider the case that the header value may not be passed and define reasonable defaults in case the value is not present.

The Semantic Objects provide some defaults for the application to work, but to prevent unexpected behavior, consider combining the BROWSER keyword with other language qualifiers. For example, lang: "BROWSER,en~,NONE" will allow the application to work for English speaking users even if they have not configured their regional settings.

Language Preference Order for Fetching

Language specs can be provided at different levels. The spec at a given level will apply to lower levels if they do not specify their own lang fetching option. Consider the example:

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query humanInEnglish { human(lang: "en") { name desc { value lang } film(lang: "it,de") { name desc { value lang } vehicle { name desc(lang: "de") { value lang } } } homeworld { name desc { value lang } } } }

In this example query, the language spec for fetching is applied at multiple levels:

  • When applied at the query level, it will apply for all Literal properties. For our example, it means that Planet.desc and Planet.resident.homeworld.desc will have only English language descriptions, if any.
  • When applied to a complex property like Planet.film, it overrides the upper level (the query in this case) and changes the default behavior for the Planet.film.desc to English, or, if an English language description is not present, to German.
  • When applied to a literal property’s lang argument, it will override any spec coming from an upper level. In our example, the Planet.film.vehicle.desc and Planet.resident.desc have their own language fetch specs, so they will be used for fetching the descriptions for these objects.

If the query does not define any language fetch spec (or lang: null is provided), there are two possible outcomes:

  • The values will be filtered based on the language fetch configuration in the SOML model for the langString or stringOrLangString properties. For more information, see the SOML property language configurations.
  • All values will be returned.

Hint

Language preference is applicable not only for queries, but also for mutations. It can be used for the result part of the mutation the same way it is for the queries. For more information, check the Object creation section.

Language Filtering

While the previous section describes using language specs to fetch language-tagged values, here we will see how to filter objects by language-tagged values of a field. Make sure that the object has values and/or does not have values with specified languages.

Language specs for filtering are similar to language specs for fetching, but simpler:

  • An object satisfies a language spec if it has at least one matching value.
  • To find objects that do not have matching values, you cannot use exclusion (-). Use NOT at the outer level (see examples below).
  • The mode is always ALL because all conditions are checked.
  • ANY is not allowed because it is a vacuous check.
  • -ANY is not allowed because it would exclude all objects.
  • The same conditions about language subsumption and exclusion compatibility apply as in the previous section.
  • BROWSER is not allowed because it makes no sense to search for objects having a value in a user-determined language.

Language specs for filtering add the following features:

  • UNIQ: find objects that do not have multiple values in the same language. This is intended to check SKOS Integrity Condition S14.
  • -UNIQ: find objects that have multiple values in the same language. This can be used to find and fix such objects.
  • These checks pertain to empty language tags.
  • You can combine them with language tags to refine the list of languages being checked.
  • The UNIQ check must come last and be separated with semicolon.

Examples of filtering by language spec:

GraphQL Query Return objects that
{obj(where: {field: {lang: "en"}}) {...} have an English-language value
{obj(where: {field: {lang: "en~,-en-US"}}) {...} have value in any English or “dialect” except American English
{obj(where: {field: {lang: "-en-US"}}) {...} have a value in any language except American English (including empty language)
{obj(where: {NOT: {field: {lang: "en-US"}}}) {...} do not have a value in American English
{obj(where: {field: {lang: "UNIQ"}}) {...} do not have multiple values in the same language
{obj(where: {field: {lang: "-UNIQ"}}) {...} have multiple values in the same language
{obj(where: {field: {lang: "~;-UNIQ"}}) {...} have multiple values in the same non-empty language
{obj(where: {field: {lang: "en;-UNIQ"}}) {...} have multiple values in English
{obj(where: {field: {lang: "en~;-UNIQ"}}) {...} have multiple values in the same language, which is an English “dialect”
{obj(where: {field: {value: {IRE: "foo"}, lang: "-UNIQ"}}) {...} have multiple values in the same language that match the string “foo”

Examples of invalid language specs for filtering:

Language Spec Error
ALL:-en Mode ALL is implied when filtering by language and should not be specified
ANY,en ANY is not allowed when filtering by language because it is a vacuous check
-ANY -ANY is not allowed when filtering by language because it would exclude all objects
en,en~ Language en is subsumed by en~ so it has no effect
en~,en-GB Language en-GB is more specific than en~ so it has no effect
en~,en-GB~ Language en-GB~ is more specific than en~ so it has no effect
en,fr,bg,en Language en is specified more than once
en-GB,en,-en~
  • Language exclusion -en~ is more general than language en-GB so the language has no effect
  • Language exclusion -en~ is more general than language en so the language has no effect

Examples:

All objects in the schema.yaml have a multilingual property desc, which can be used for trying the language filtering functionality.

Find all Characters that have values with non-empty language:

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query charactersWithNoneEmptyLangs { character(where: {desc: {lang: "~"}}) { name desc { value lang } } }

All Film-s that have description in German, and we fetch only the German descriptions:

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query filmsWithGermanDescription { film(where: {desc: {lang: "de"}}) { name desc(lang: "de") { value lang } } }

All Character-s that have non-English description. Try removing the value fetching filter -en to see how the response changes.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query characterWithNoneEnglishDescription { character(where: {desc: {lang: "~,-en~"}}) { name desc(lang: "-en") { value lang } } }

Find Character-s that do not have unique language description. Try changing the filter to UNIQ.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query characterWithNoneUniqueDescription { character(where: {desc: {lang: "-UNIQ"}}) { name desc { value lang } } }
{ "data": { "character": [] } }

Combine Multiple Arguments

To filter and constrain lists with more complex expressions, we can combine where, orderBy, limit, and offset.

Let’s make some complex queries in order to fetch specific data.

Examples:

All characters ordered in descending character name order, where the character appeared in the film A New Hope and the characters films are filtered to only include A New Hope with the character’s films ordered in ascending releaseDate order.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query charactersInDescendingNameOrderWhereFilmWasNewHopeOrderedByReleaseDate { character(orderBy: {name: DESC}, where: {film: {name: {EQ: "A New Hope"}}}) { name film(orderBy: {releaseDate: ASC}, where: {name: {EQ: "A New Hope"}}) { name releaseDate } } }

Cycle Queries

GraphQL allows cyclic queries, such as the one shown below. They are virtually endless and can be considered DoS queries. To protect the database, we have added two limits:

  • sparql.endpoint.maxTupleResults - maximum number of tuples that can be returned from the DB for one request property.
    Default value is set to 5_000_000. If it is exceeded, the query will be terminated and an error will be thrown. No data will be returned in this case as it is not possible to return a meaningful response.
  • graphql.query.depthLimit - limit on the depth of the GraphQL query.
    Default value is set to 15. If it is exceeded, an error will be thrown notifying the user the query depth limit is 15.
Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query cyclicQuery { character { film { character { film { character { film { character { film { character { film { character { film { character { film { character { film { character { film { character { film { character { film { id } } } } } } } } } } } } } } } } } } } } } } }
{ "errors": [ { "message": "The maximum allowed query depth is '15'" } ] }

Multiple Queries in a Request

If multiple queries are part of the same query request, they are executed in parallel, and the individual responses are collated and returned. You can fetch objects of different unrelated types in the same query.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query multipleRootObjects { film { name releaseDate } starship{ name cargoCapacity costInCredits } }

Variables in Queries

A GraphQL query can be parameterized with variables, maximizing query reuse, and avoiding costly string building in clients at runtime.

If not defined as constant, a variable can be supplied for an input value.

Variables must be defined at the top of an operation and are in scope throughout the execution of that operation.

Let’s try it out. Insert the following variables in the Query variables section of the editor below:

{
    "ids":["https://swapi.co/resource/vehicle/38","https://swapi.co/resource/vehicle/44"]
}
Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query starship_by_pilot_vehicle_id ($ids: [ID!]!) { starship(where:{ALL_EXISTS: {pilot: {vehicle: {ID: $ids}}}}, limit: 2) { id name pilot(orderBy: {name: DESC}) { id name vehicle(orderBy: {name: DESC}) { id name } } } }

In the example above, we have defined a variable ids.

  • ($ids: [ID!]!) - here we define the variable and say that we expect ID to be passed for it.
  • And here is the usage of the variable in the query filter: (where:{ALL_EXISTS: {pilot: {vehicle:  {ID: $ids}}}}, limit: 2)

Fragment and Aliases

Fragments

Fragments are the primary unit of composition in GraphQL.

Fragments allow for the reuse of common repeated selections of fields, reducing duplicated text in the document. Inline Fragments can be used directly within a selection to condition upon a type condition when querying against an interface or union.

For example, if we want to fetch some common information about a film, we would have the following query:

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query usingFragments { film(ID: "https://swapi.co/resource/film/1") { id name role { roleType person { name } character { name } } planet { id name resident { id name film { id name role { roleType person { name } character { name } } } } } } }

The repeated fields can be extracted into a fragment and composed by a parent fragment or query.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query usingFragments { film(ID: "https://swapi.co/resource/film/1") { ...commonFilmProperties planet { id name resident { id name film { ...commonFilmProperties } } } } } fragment commonFilmProperties on Film { id name role { roleType person { name } character { name } } }

Fragments are consumed by using the spread operator (…). All fields selected by the fragment will be added to the query field selection at the same level as the fragment invocation. This happens through multiple levels of fragment spreads.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query usingFragments { film(ID: "https://swapi.co/resource/film/1") { ...detailedFilmProperties planet { id name resident { id name film { ...commonFilmProperties } } } } } fragment commonFilmProperties on Film { id name role { roleType person { name } character { name } } } fragment detailedFilmProperties on Film { releaseDate desc { value lang } episodeId ...commonFilmProperties }

Inline Fragments

Fragments can be defined inline within a selection set. This is done to conditionally include fields based on their runtime type.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query film1 { film(ID: "https://swapi.co/resource/film/1") { id name character { type name ... on Droid { name id } ... on Human { name eyeColor skinColor } } } }

Note that the name field is requested separately for character, Droid, and Human, but it is returned only once for each character. When more than one fields of the same name are executed in parallel, their selection sets are merged together when completing the value in order to continue execution of the sub‐selection sets.

Aliases

GraphQL Aliases allows you to rename the result of a field to anything you want. Let’s say you want to have the same top level field in the same query with different arguments We can achieve this by using alias for film.

For example:

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query usingAliases { Film1:film(ID: "https://swapi.co/resource/film/1") { id name releaseDate } Film2:film(orderBy:{episodeId:DESC}) { id name releaseDate episodeId openingCrawl } }

Aliases are necessary for the query to work. If you run the query without aliases, it will return an error:

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJNODctcWV3SldXTWRMRjIzNUtXUmluTlp4TDA0ZngzIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE3MjkyNDk4MTksImlhdCI6MTY5ODE0NTgxOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiZTlmOWQzNGQtZThmMS00ODM1LTlkMzAtOWRjNmU5YjQ4ZmMzIiwianRpIjoiODZjNTIzYzEtYzQzNC00MWZiLWFkOTctYWU2MDY5MjgxYWM4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXSwiZGF0YSI6e319.yVwuhsZQQgbk6ASaaA5iS2z_E7ThqPpMtYKfxjVcND8
true
query withoutAliases { film(ID: "https://swapi.co/resource/film/1") { id name releaseDate } film(orderBy:{episodeId:DESC}) { id name releaseDate episodeId openingCrawl } }
{ "errors": [ { "message": "ERROR: 'film' : fields have different arguments @ ''", "locations": [ { "line": 2, "column": 8 }, { "line": 7, "column": 8 } ], "extensions": { "classification": "ValidationError" } } ] }

GraphQL Aliases are dynamic, written on the client making the request. This is a workaround for use cases where you want the selection set to be named more readable. It is not prudent to write this for every query from every client making this request for modifying trivial fields.

Query Data Control

Controlling how queries are evaluated is an important part of any SPARQL based database. As such, the Semantic Objects provide several capabilities that can affect query evaluation. The section below describes the following functionalities:

Dataset selection

SPARQL offers ways for changing the dataset against which a given query is evaluated. For queries, this is done using the FROM keyword used to specify what is included in the default dataset and which graphs to be included during query evaluation. In GraphQL, this is represented as the from query argument.

See more about SPARQL datasets in the SPARQL query specification here.

See more about SPARQL queries and datasets in the GraphDB documentation here.

Here is an example GraphQL query that specifies a source dataset when evaluating a query:

query {
  object(from: "https://swapi.co/resource/humans") {
     id
  }
}

Note

GraphDB has a set of system named graphs controlling the query behavior that will also affect the GraphQL result. These special graphs can be used with the from argument.

The complete list of special graphs can be found here.

Note

FROM NAMED currently is not supported. If you need support for it, consider contacting the Platform Support.

Change repository

Along with changing the query dataset, GraphQL queries can also be used to change the target repository altogether. The only requirement is that the other repository is accessible on the same server address.

The target repository is specified using the repository argument in GraphQL query like so:

query {
  object(repository: "otherRepository") {
     id
  }
}

Alternatively, the target repository can be provided via the X-Repository HTTP header. When supplied this way, the value will apply to all queries and mutations in the request.

Note

The query configuration has higher precedence over the request header value.

If security is enabled, it can also be read from the JSON Web Token (JWT) claim. To enable this, the configuration sparql.endpoint.repository must be defined as ${ctx.claims.<claim_key>:<default_repository>}, where:

  • claim_key is the name of the JWT claim from which the repository identifier can be read
  • default_repository is the repository to be used if no such key and value are found in the claims of the authenticated user. An example configuration that reads a claim named repository and default repository named soaas would look like this: ${ctx.claims.repository:soaas}.

The access to the repositories can be restricted by using the Semantic Objects configuration sparql.endpoint.repositoryWhitelist. If not empty, the only accessible repositories will be the ones listed there.

It can also be used to effectively disable the functionality completely by listing the only one available repository like so:

sparql.endpoint.repository: soaas
sparql.endpoint.repositoryWhitelist: soaas

If no specific information about the target repository is provided in the query or the HTTP header, the repository value will be taken from the SOML configuration, if available. The SOML schema configuration looks like this:

config:
  repository: soaas

If the configured SPARQL endpoint server has security enabled, the configured user must have access to all repositories that they need to access.

Inference

The default behavior of the Semantic Objects (unless specified otherwise) is to include the inferred statements from the underlying repository when evaluating the queries and mutations.

See more about inference and inferred statements here.

In each query, the includeInferred parameter can be used to change the inference for that particular query:

query {
   object(includeInferred: false) {
       id
       name
   }
}

The HTTP header X-Include-Inferred: false can also be used to disable the inference for the entire GraphQL request.

Note

The query configuration has higher precedence over the request header value.

Note

This configuration is applicable for any RDF4J-based endpoints.

The way inferred statements are included in the query evaluation can also be changed at SOML schema level in the config section.

The SOML config value will be applied if there is no explicit override in a request via a query argument or an HTTP header.

config:
  includeInferred: false

Expand over owl:sameAs

Note

The following section is applicable only if the Semantic Objects communicate with a GraphDB repository.

The default behavior of the Semantic Objects (unless specified otherwise) is to join results for subjects that are linked with the owl:sameAs predicate when evaluating the queries and mutations, but only if the support for it is enabled at repository and ruleset level.

See more about owl:sameAs and how it is implemented in GraphDB here.

The default behavior for owl:sameAs expansion can be configured at SOML schema level in the config section. The value there will be applied if a particular request does not override it explicitly.

config:
  expandOwlSameAs: true

In each query, the parameter expandOwlSameAs can be used to change the owl:sameAs behavior for that particular query.

query {
   object(expandOwlSameAs: false) {
       id
       name
   }
}

The HTTP header X-Expand-Over-Owl-SameAs: false can also be used to disable the owl:sameAs resolution for the entire GraphQL request.

Note

The query configuration has higher precedence over the request header value.

An alternative to the argument expandOwlSameAs: false is to use from: "onto:disable-sameAs" as this is the same behavior that the Semantic Objects apply under the hood.

query {
   object(from: "onto:disable-sameAs") {
       id
       name
   }
}

The default behavior for owl:sameAs expansion could be configured on SOML schema level in the config section. The value there will be applied if a particular request does not override it explicitly.

config:
  expandOwlSameAs: true