GraphQL

Gentics Mesh is also able to process GraphQL queries. You can use GraphQL to directly specify what fields should be retrieved and retrieve deeply nested data sets. Internally, Gentics Mesh will resolve your query and traverse your content graph to fetch only the data you specified.

The GraphQL API can thus be used to prepare a single request which returns all data needed to render a specific page.

Possible use cases are:

  • Loading multiple nodes using the webroot path.

  • Generating a custom navigation which only includes the information you need.

  • Invoking multiple search requests to find a set of specific nodes.

  • Resolve links within the content of a node.

  • Load users, roles, groups

  • Load tags, tag families, schema and microschema information

Live Examples

If you want to learn more about the GraphQL syntax take a look at the good documentation.

Loading current user

{ me { username, uuid } }

Loading basic fields of a node

{ node(path: "/yachts/pelorus") { fields { ... on vehicle { name description } } } }

Loading a node via uuid

{ node(uuid: "28f42d43a7604114b42d43a7602114da") { path } }

Loading referenced fields of a node

Nodes can be linked together in various way. One way is the regular parent-child relationship. Another way is by using node fields. The demo data contains vehicles which each is linked to a vehicle image. In order to present the vehicle we also need to retrieve the image path and other information.

{ node(path: "/yachts/pelorus") { fields { ... on vehicle { name description # The vehicleImage field is a node field # which points to a vehicle image node vehicleImage { path # We need to specify what kind of node we expect. # Otherwise we can't retrieve the image # binary field information. fields { ... on vehicleImage { image { width height fileSize mimeType dominantColor } } } } } } } }

The search query is an escaped JSON object which represents the a regular Elasticsearch query.

{ # Search for all nodes which contain the string 'car' in the content nodes(query: "{\"query\":{\"query_string\":{\"query\":\"car\"}}}") { elements { uuid fields { ... on vehicle { slug } } } # Total amount of found results totalCount } }

Using pagination

Similar to the REST API a value based pagination system is implemented.

{ nodes(perPage: 2, page: 2) { elements { uuid } # Total amount of found elements totalCount # Total amount of found pages. Each page has a size of 2 pageCount # Size of the current page. The last page may only contain a few elements size # Current per page size perPage # Flag which indicates whether another page exists hasNextPage # Flag which indicates whether a previous page exists hasPreviousPage } }

Multilanguage support

The node will automatically be loaded in the language which matches up with the provided webroot path. A webroot path which points to an english node will yield the english content. Subsequent loading a node using the german path will yield the german content. It is important to node that Gentics Mesh tries to stick to a language as much as possible. Loading additional referenced nodes of an german node via either the children or a node field will return the german content if such content could be found. The fallback to the configured default language will be applied if no other matching content found be found. Null will be returned if this also fails.

It is possible to load a found node in a different language using the node field as shown in the example.

{ node(path: "/yachts/pelorus") { availableLanguages node(lang: "de") { language } } }

Filtering

Any time a node list is requested, you can provide a filter object as a parameter to narrow down the result.

Here are a few examples:

Loading nodes from a specific schema

The SchemaFilter matches nodes with a specific schema name.

{ # Loading node with path "/". This is the root folder. node(path: "/") { # Applying a filter on its children. children(filter: { # We filter for the schema with the name category. schema: { is: category } }) { elements { uuid fields { ... on category { name } } } } } }

Filter nodes with regular expressions

The StringFilter offers various ways to filter strings. One example is regular expressions. In this example we get all nodes with the schema vehicle. We check if their name field ends with a number.

{ # Get all nodes and apply filter nodes(filter: { # Get nodes from schema "vehicle" schema: { is: vehicle } # Filter by fields fields: { # If item in result is a "vehicle", # apply this filter vehicle: { # Filter the field "name" with a # regular expression name: { regex: "[0-9]$" } } } }) { elements { uuid fields { ... on vehicle { name } } } } }

Combining different filters

Combine multiple filters to further narrow down your results. One example is the OrFilter. We get the same nodes as in the previous example. Additionally we also get all vehicles that have a price lower than 200.000.

{ # Get all nodes and apply filter nodes(filter: { # Get nodes from schema "vehicle" schema: { is: vehicle } # Filter by fields fields: { # If item in result is a "vehicle", # apply this filter vehicle: { # Test if any of the following filters apply or: [ # Filter the field "name" with a # regular expression {name: { regex: "[0-9]$" }} # Get vehicles that have a price # less than 200.000 {price: { lt:200000 }} ] } } }) { elements { uuid fields { ... on vehicle { name price } } } } }

Filtering limitations

When filtering by fields of a node, it is currently only possible to filter by fields of the following types:

  • string

  • html

  • number

  • date

  • boolean

A note on GraphiQL
Edit the above examples and experiment with the API. Use the GraphiQL autocompletion (press ctrl+space while typing your query) to see what options are available. Check the documentation explorer (in the top-right corner) to find out more details.
Try it in your own installation
Your instance of Gentics Mesh comes with the GraphiQL Browser as well.

Comparison to Elasticsearch

Many tasks can be done by both the search and the filtering feature. Here are a few tips that help you decide which technology is suited best for your needs:

  • GraphQL filtering is independent of Elasticsearch. If you don’t want to use Elasticsearch, GraphQL filtering is still available.

  • GraphQL filtering is faster when dealing with small datasets. There is less overhead compared to Elasticsearch. GraphQL filtering iterates over the source set of elements and applies the filter until enough nodes have been found for the response.

  • Elasticsearch is faster when dealing with large datasets, because it uses an index to access its documents.

  • Elasticsearch is better suited for full text search queries from an end user because you can precisely tune the index to your requirements.

GraphiQL Browser

We have integrated the interactive GraphiQL[1] browser into Gentics Mesh so you can easily play with the API.

Try the example
Live Demo

Alternatively, you can download Gentics Mesh and test the API locally. Once authenticated you can access the interactive GraphiQL browser at /api/v1/:projectName/graphql/browser/ .

The GraphiQL browser currently does not support the release or version query parameter.

Limitations

  • At the moment, the GraphQL API can currently only be used for read-only operations. Modifying data with via mutations is currently not supported.

  • GraphQL queries are restricted to a specific project. It is not possible to query data across multiple projects.

  • GraphQL queries are restricted to a specific release. The scope of the release can be changed by adding the ?release query parameter.

1. GraphiQL is owned and developed by Facebook Inc. Usage is subject to the LICENSE AGREEMENT For GraphiQL software.