Features

This section will be about the features of Gentics Mesh. Each will be described in detail including examples and references to relevant parts of the API or related tutorials.

Content Trees

Gentics Mesh provides the means to organize your contents in terms of a content tree, or rather a node tree. Nodes can be hierarchically structured if a container schema is provided. For example, a book node can act as a container for chapter nodes. Alternatively, consider the example in our demo app, where vehicles are structured within categories.

While it is perfectly legitimate to organize your contents in a simple, flat structure with tagging and referencing, content trees come with big a bonus: they inherently allow for automatically generated hierarchical navigation menus, breadcrumbs and pretty URLs. This furthermore means routes are not hard-coded in your app but can be defined dynamically by content editors using the Gentics Mesh user interface.

To get you started, Gentics Mesh is shipped with a generic folder schema allowing you to follow the well-known file system paradigm for hierarchically organizing your content in a tree.

There are two properties when defining a schema for your nodes that are of importance in this respect.

  1. container: if true, nodes can contain child nodes and build a node tree.

  2. segmentField: allows to specify which schema field should be considered the path segment for the current node, i.e., it’s the basis for building URLs.

Let us consider the following example on the basis of our demo app to demonstrate how these properties work together to support navigation menus, breadcrumbs and pretty URLs:

Gentics Mesh Example of organizing content in a node tree

Within the demo project vehicles are organized in three different categories. The nodes Automobiles, Aircrafts and Yachts of type category serve as containers for nodes of type vehicle, e.g., the node Ford GT in category Automobiles.

The schema category has the container property set to true, thus allowing nodes of type category to have child nodes. The schema’s segmentField is specified to be the slug field. Thus, the resulting value for the path property of node Automobiles is /automobiles.

The schema vehicle has the container property set to false. The schema’s segmentField is again specified to be the slug field. Thus, the resulting value for the path property of node Ford GT is /automobiles/ford-gt.

Pretty URLs

Instead of relying on UUIDs to link your content, you can use pretty URLs like https://yourapp.com/automobiles/ford-gt. For each node, Gentics Mesh will provide you with a human readable path. Likewise, you can query your content using WebRoot paths instead of using UUIDs (see WebRoot API).

The segmentField is used to build the path of a specific node. According to the nodes’ schemas in our example, the path /automobiles/ford-gt for the node Ford GT is built using the slug field of the vehicle node, i.e. Ford GT, and the slug field of the category node, i.e. Automobiles.

Gentics Mesh Example for Building Pretty URLs

The path property as well as the languagesPath property (for available language variants) of a node can be queried using the /api/v1/projectName/nodes/:nodeUuid endpoint together with the query parameter resolveLinks. Alternatively, the WebRoot API can be used /api/v1/:projectName/webroot/:path For more details see the documentation on node and WebRoot API, respectively.

API endpoints

Description API endpoint

Get the node with the given UUID.

GET /api/v1/:projectName/nodes/:nodeUuid

Response Sample

{
  "uuid" : "fc3c85be82584ae2bc85be82588ae2b0",
  "creator" : {
    "uuid" : "a93e95f316114659be95f31611265997"
  },
  "created" : "2017-05-29T09:56:16Z",
  "editor" : {
    "uuid" : "a93e95f316114659be95f31611265997"
  },
  "edited" : "2017-05-29T09:56:22Z",
  "language" : "en",
  "availableLanguages" : [ "en" ],
  "languagePaths" : {
    "en" : "/automobiles/ford-gt"
  },
  "parentNode" : {
    "projectName" : "demo",
    "uuid" : "ca6c7df3f45b48d4ac7df3f45ba8d42f",
    "displayName" : "Automobiles",
    "path" : "/automobiles",
    "schema" : {
      "name" : "category",
      "uuid" : "2ca2362b041247c4a2362b041227c4da"
    }
  },
  "tags" : [ {
    "name" : "Gasoline",
    "uuid" : "1c51487f8e8043c291487f8e8053c2c1",
    "tagFamily" : "Fuels"
  }, {
    "name" : "Blue",
    "uuid" : "6e6f1d9f055447d2af1d9f055417d289",
    "tagFamily" : "Colors"
  }, {
    "name" : "White",
    "uuid" : "94fec98d6f114e81bec98d6f118e81cc",
    "tagFamily" : "Colors"
  } ],
  "project" : {
    "name" : "demo",
    "uuid" : "217f8c981ada4642bf8c981adaa642c3"
  },
  "childrenInfo" : { },
  "schema" : {
    "name" : "vehicle",
    "uuid" : "2aa83a2b3cba40a1a83a2b3cba90a1de",
    "version" : 1
  },
  "container" : false,
  "displayField" : "name",
  "fields" : {
    "slug" : "ford-gt",
    "name" : "Ford GT",
    "weight" : 1520,
    "SKU" : 1,
    "price" : 139995,
    "stocklevel" : 20,
    "description" : "The Ford GT is an American mid-engine two-seater sports car that was produced by Ford for the 2005 through 2006 model years.",
    "vehicleImage" : {
      "uuid" : "df8beb3922c94ea28beb3922c94ea2f6",
      "path" : "/images/ford-gt.jpg",
      "languagePaths" : {
        "en" : "/images/ford-gt.jpg"
      }
    }
  },
  "path" : "/automobiles/ford-gt",
  "breadcrumb" : [ {
    "projectName" : "demo",
    "uuid" : "ca6c7df3f45b48d4ac7df3f45ba8d42f",
    "displayName" : "Automobiles",
    "path" : "/automobiles",
    "schema" : {
      "name" : "category",
      "uuid" : "2ca2362b041247c4a2362b041227c4da"
    }
  } ],
  "version" : {
    "uuid" : "677bf76c8c624e2fbbf76c8c62be2fa0",
    "number" : "1.0"
  },
  "permissions" : {
    "create" : false,
    "read" : true,
    "update" : false,
    "delete" : false,
    "publish" : false,
    "readPublished" : false
  }
}

When organizing your content in terms of a node tree, Gentics Mesh offers two ways of generating a nested navigation response.

The API endpoint /api/v1/:projectName/nodes/:nodeUuid/navigation returns a navigation object for the provided node, while the /api/v1/:projectName/navroot/:path API endpoint returns a navigation object for a node which is located using a given path. Each endpoint will return a navigation response which contains the nested navigation tree structure.

By default, only container nodes are included in a navigation response. The includeAll query parameter will include all nodes, if set to true. The maxDepth parameter may be used to limit the navigation depth. In order to include the path property in the navigation response, the resolveLinks query parameter can be used.

Gentics Mesh Example for Building Navigation Menus

The demo app includes a navigation object showing just the top-level elements Automobiles, Aircraft, and Yachts as well as the Home link. All the elements can be easily queried using the available navigation endpoints. In particular, the example uses the /api/v1/:projectName/navroot/:path API endpoint, with the URL parameter :path querying the project root node, i.e., / together with query parameter ?maxDepth limiting the resulting nested JSON object to the top-level nodes.

API endpoints

Description API endpoint

Returns a navigation object for the provided node.

GET /api/v1/:projectName/nodes/:nodeUuid/navigation

Return a navigation for the node which is located using the given path.

GET /api/v1/:projectName/navroot/:path

Properties

Name Type Description

node

object

Detailed node information of the given UUID.

children

array

List of further child elements of the node.

uuid

string

UUID of the node within this navigation element.

Query Parameters

Name Type Description

includeAll

boolean (default: false)

If set to true all nodes will be included in the response. By default only container nodes are included in a navigation response.

maxDepth

number (default: 10)

Specifies the maximum depth for the requested navigation tree structure.

lang

string

The ISO 639-1 language tag of the language which should be loaded. Fallback handling can be applied by specifying multiple languages in a comma-separated list. The first matching language will be returned. If omitted or the requested language is not available then the defaultLanguage as configured in mesh.yml will be returned.

release

string

Specifies the release UUID to be used for loading data. The latest project release will be used if this parameter is omitted.

resolveLinks

string

The resolveLinks parameter can be set to either short, medium or full. Links will automatically be resolved and replaced by the resolved WebRoot path. No resolving occurs if the query parameter is omitted.

role

string

The role query parameter takes a UUID and may be used in order to add permission information to the response which is related to the specified role. When used, the response will include the rolePerms property which lists the permissions for the specified role on this node. E.g., this may be useful when you are logged in as administrator but want to retrieve the editor role permissions on a given node.

version

string

Specifies the version of the node’s language variant, e.g.: 0.1, 1.0, draft, published.

Response Sample

Retrieving a navigation object using the projects root node / including the top level navigation menu items.

The same can be achieved using the node specific navigation endpoint. In this case you can specify the root node of your navigation by providing the node uuid.

{
  "uuid" : "72dbee3975054fce9bee397505cfcec5",
  "node" : {
    "uuid" : "72dbee3975054fce9bee397505cfcec5",
    "creator" : {
      "uuid" : "a93e95f316114659be95f31611265997"
    },
    "created" : "2017-05-29T09:55:43Z",
    "editor" : {
      "uuid" : "a93e95f316114659be95f31611265997"
    },
    "edited" : "2017-05-29T09:56:22Z",
    "language" : "en",
    "availableLanguages" : [ "en" ],
    "languagePaths" : {
      "en" : "/"
    },
    "tags" : [ ],
    "project" : {
      "name" : "demo",
      "uuid" : "217f8c981ada4642bf8c981adaa642c3"
    },
    "childrenInfo" : {
      "folder" : {
        "schemaUuid" : "5cc780af998c4d228780af998ccd2240",
        "count" : 1
      },
      "category" : {
        "schemaUuid" : "2ca2362b041247c4a2362b041227c4da",
        "count" : 3
      }
    },
    "schema" : {
      "name" : "folder",
      "uuid" : "5cc780af998c4d228780af998ccd2240",
      "version" : 1
    },
    "container" : true,
    "displayField" : "name",
    "fields" : { },
    "path" : "/",
    "breadcrumb" : [ ],
    "version" : {
      "uuid" : "df10370c82be422290370c82be62229f",
      "number" : "1.0"
    },
    "permissions" : {
      "create" : false,
      "read" : true,
      "update" : false,
      "delete" : false,
      "publish" : false,
      "readPublished" : false
    }
  },
  "children" : [ {
    "uuid" : "15d5ef7a9abf416d95ef7a9abf316d68",
    "node" : {
      "uuid" : "15d5ef7a9abf416d95ef7a9abf316d68",
      "creator" : {
        "uuid" : "a93e95f316114659be95f31611265997"
      },
      "created" : "2017-05-29T09:56:10Z",
      "editor" : {
        "uuid" : "a93e95f316114659be95f31611265997"
      },
      "edited" : "2017-05-29T09:56:22Z",
      "language" : "en",
      "availableLanguages" : [ "en" ],
      "languagePaths" : {
        "en" : "/images"
      },
      "parentNode" : {
        "projectName" : "demo",
        "uuid" : "72dbee3975054fce9bee397505cfcec5",
        "path" : "/",
        "schema" : {
          "name" : "folder",
          "uuid" : "5cc780af998c4d228780af998ccd2240"
        }
      },
      "tags" : [ ],
      "project" : {
        "name" : "demo",
        "uuid" : "217f8c981ada4642bf8c981adaa642c3"
      },
      "childrenInfo" : {
        "vehicleImage" : {
          "schemaUuid" : "b12272150db4490ea272150db4190e72",
          "count" : 10
        }
      },
      "schema" : {
        "name" : "folder",
        "uuid" : "5cc780af998c4d228780af998ccd2240",
        "version" : 1
      },
      "container" : true,
      "displayField" : "name",
      "fields" : {
        "slug" : "images",
        "name" : "Vehicle Images"
      },
      "path" : "/images",
      "breadcrumb" : [ ],
      "version" : {
        "uuid" : "b1f2c06e45db4e0db2c06e45dbfe0d25",
        "number" : "1.0"
      },
      "permissions" : {
        "create" : false,
        "read" : true,
        "update" : false,
        "delete" : false,
        "publish" : false,
        "readPublished" : false
      }
    }
  }, {
    "uuid" : "ca6c7df3f45b48d4ac7df3f45ba8d42f",
    "node" : {
      "uuid" : "ca6c7df3f45b48d4ac7df3f45ba8d42f",
      "creator" : {
        "uuid" : "a93e95f316114659be95f31611265997"
      },
      "created" : "2017-05-29T09:56:16Z",
      "editor" : {
        "uuid" : "a93e95f316114659be95f31611265997"
      },
      "edited" : "2017-05-29T09:56:22Z",
      "language" : "en",
      "availableLanguages" : [ "en" ],
      "languagePaths" : {
        "en" : "/automobiles"
      },
      "parentNode" : {
        "projectName" : "demo",
        "uuid" : "72dbee3975054fce9bee397505cfcec5",
        "path" : "/",
        "schema" : {
          "name" : "folder",
          "uuid" : "5cc780af998c4d228780af998ccd2240"
        }
      },
      "tags" : [ ],
      "project" : {
        "name" : "demo",
        "uuid" : "217f8c981ada4642bf8c981adaa642c3"
      },
      "childrenInfo" : {
        "vehicle" : {
          "schemaUuid" : "2aa83a2b3cba40a1a83a2b3cba90a1de",
          "count" : 5
        }
      },
      "schema" : {
        "name" : "category",
        "uuid" : "2ca2362b041247c4a2362b041227c4da",
        "version" : 1
      },
      "container" : true,
      "displayField" : "name",
      "fields" : {
        "name" : "Automobiles",
        "slug" : "automobiles"
      },
      "path" : "/automobiles",
      "breadcrumb" : [ ],
      "version" : {
        "uuid" : "2cadceaea20343e8adceaea20313e842",
        "number" : "1.0"
      },
      "permissions" : {
        "create" : false,
        "read" : true,
        "update" : false,
        "delete" : false,
        "publish" : false,
        "readPublished" : false
      }
    }
  }, {
    "uuid" : "21203632520b4d19a03632520b2d19c1",
    "node" : {
      "uuid" : "21203632520b4d19a03632520b2d19c1",
      "creator" : {
        "uuid" : "a93e95f316114659be95f31611265997"
      },
      "created" : "2017-05-29T09:56:19Z",
      "editor" : {
        "uuid" : "a93e95f316114659be95f31611265997"
      },
      "edited" : "2017-05-29T09:56:22Z",
      "language" : "en",
      "availableLanguages" : [ "en" ],
      "languagePaths" : {
        "en" : "/aircrafts"
      },
      "parentNode" : {
        "projectName" : "demo",
        "uuid" : "72dbee3975054fce9bee397505cfcec5",
        "path" : "/",
        "schema" : {
          "name" : "folder",
          "uuid" : "5cc780af998c4d228780af998ccd2240"
        }
      },
      "tags" : [ ],
      "project" : {
        "name" : "demo",
        "uuid" : "217f8c981ada4642bf8c981adaa642c3"
      },
      "childrenInfo" : {
        "vehicle" : {
          "schemaUuid" : "2aa83a2b3cba40a1a83a2b3cba90a1de",
          "count" : 3
        }
      },
      "schema" : {
        "name" : "category",
        "uuid" : "2ca2362b041247c4a2362b041227c4da",
        "version" : 1
      },
      "container" : true,
      "displayField" : "name",
      "fields" : {
        "name" : "Aircraft",
        "slug" : "aircrafts"
      },
      "path" : "/aircrafts",
      "breadcrumb" : [ ],
      "version" : {
        "uuid" : "cb34cedeeb9c4d3db4cedeeb9c0d3d01",
        "number" : "1.0"
      },
      "permissions" : {
        "create" : false,
        "read" : true,
        "update" : false,
        "delete" : false,
        "publish" : false,
        "readPublished" : false
      }
    }
  }, {
    "uuid" : "eb2ebdcc0e894a9eaebdcc0e896a9e1d",
    "node" : {
      "uuid" : "eb2ebdcc0e894a9eaebdcc0e896a9e1d",
      "creator" : {
        "uuid" : "a93e95f316114659be95f31611265997"
      },
      "created" : "2017-05-29T09:56:21Z",
      "editor" : {
        "uuid" : "a93e95f316114659be95f31611265997"
      },
      "edited" : "2017-05-29T09:56:22Z",
      "language" : "en",
      "availableLanguages" : [ "en" ],
      "languagePaths" : {
        "en" : "/yachts"
      },
      "parentNode" : {
        "projectName" : "demo",
        "uuid" : "72dbee3975054fce9bee397505cfcec5",
        "path" : "/",
        "schema" : {
          "name" : "folder",
          "uuid" : "5cc780af998c4d228780af998ccd2240"
        }
      },
      "tags" : [ ],
      "project" : {
        "name" : "demo",
        "uuid" : "217f8c981ada4642bf8c981adaa642c3"
      },
      "childrenInfo" : {
        "vehicle" : {
          "schemaUuid" : "2aa83a2b3cba40a1a83a2b3cba90a1de",
          "count" : 2
        }
      },
      "schema" : {
        "name" : "category",
        "uuid" : "2ca2362b041247c4a2362b041227c4da",
        "version" : 1
      },
      "container" : true,
      "displayField" : "name",
      "fields" : {
        "name" : "Yachts",
        "slug" : "yachts"
      },
      "path" : "/yachts",
      "breadcrumb" : [ ],
      "version" : {
        "uuid" : "4bc10d889134438e810d889134038ed9",
        "number" : "1.0"
      },
      "permissions" : {
        "create" : false,
        "read" : true,
        "update" : false,
        "delete" : false,
        "publish" : false,
        "readPublished" : false
      }
    }
  } ]
}

Breadcrumbs

Each node in Gentics Mesh provides information on where it is located within the node tree in terms of its breadcrumb property. The property provides an array of node references representing the path from the current node up to the project root. For more details see the documentation on node.

The current node will not be included in the list, since all the information is already provided in other properties (i.e., displayField, path) of node object itself.

In our demo app example, the breadcrumb property for node Ford GT will therefore include the node Automobiles.

Gentics Mesh Example for Building Breadcumbs

The breadcrumb property will be returned in all API responses containing nodes. Using the resolveLink query parameter will also the paths of the nodes listed in the array.

API endpoints

Description API endpoint

Get all nodes of a project and return a paged list response.

GET /api/v1/projectName/nodes

Get the node with the given UUID.

GET /api/v1/:projectName/nodes/:nodeUuid

Load the node or the node’s binary data, which is located using the provided path.

GET /api/v1/:projectName/webroot/:path

Response Sample

{
  "uuid" : "fc3c85be82584ae2bc85be82588ae2b0",
  "creator" : {
    "uuid" : "a93e95f316114659be95f31611265997"
  },
  "created" : "2017-05-29T09:56:16Z",
  "editor" : {
    "uuid" : "a93e95f316114659be95f31611265997"
  },
  "edited" : "2017-05-29T09:56:22Z",
  "language" : "en",
  "availableLanguages" : [ "en" ],
  "languagePaths" : {
    "en" : "/automobiles/ford-gt"
  },
  "parentNode" : {
    "projectName" : "demo",
    "uuid" : "ca6c7df3f45b48d4ac7df3f45ba8d42f",
    "displayName" : "Automobiles",
    "path" : "/automobiles",
    "schema" : {
      "name" : "category",
      "uuid" : "2ca2362b041247c4a2362b041227c4da"
    }
  },
  "tags" : [ {
    "name" : "Gasoline",
    "uuid" : "1c51487f8e8043c291487f8e8053c2c1",
    "tagFamily" : "Fuels"
  }, {
    "name" : "Blue",
    "uuid" : "6e6f1d9f055447d2af1d9f055417d289",
    "tagFamily" : "Colors"
  }, {
    "name" : "White",
    "uuid" : "94fec98d6f114e81bec98d6f118e81cc",
    "tagFamily" : "Colors"
  } ],
  "project" : {
    "name" : "demo",
    "uuid" : "217f8c981ada4642bf8c981adaa642c3"
  },
  "childrenInfo" : { },
  "schema" : {
    "name" : "vehicle",
    "uuid" : "2aa83a2b3cba40a1a83a2b3cba90a1de",
    "version" : 1
  },
  "container" : false,
  "displayField" : "name",
  "fields" : {
    "slug" : "ford-gt",
    "name" : "Ford GT",
    "weight" : 1520,
    "SKU" : 1,
    "price" : 139995,
    "stocklevel" : 20,
    "description" : "The Ford GT is an American mid-engine two-seater sports car that was produced by Ford for the 2005 through 2006 model years.",
    "vehicleImage" : {
      "uuid" : "df8beb3922c94ea28beb3922c94ea2f6",
      "path" : "/images/ford-gt.jpg",
      "languagePaths" : {
        "en" : "/images/ford-gt.jpg"
      }
    }
  },
  "path" : "/automobiles/ford-gt",
  "breadcrumb" : [ {
    "projectName" : "demo",
    "uuid" : "ca6c7df3f45b48d4ac7df3f45ba8d42f",
    "displayName" : "Automobiles",
    "path" : "/automobiles",
    "schema" : {
      "name" : "category",
      "uuid" : "2ca2362b041247c4a2362b041227c4da"
    }
  } ],
  "version" : {
    "uuid" : "677bf76c8c624e2fbbf76c8c62be2fa0",
    "number" : "1.0"
  },
  "permissions" : {
    "create" : false,
    "read" : true,
    "update" : false,
    "delete" : false,
    "publish" : false,
    "readPublished" : false
  }
}

Fetch Content with WebRoot Paths

The WebRoot API is an alternative way for fetching content from Gentics Mesh. Other than accessing nodes with their UUID, one can use the way more intuitive WebRoot paths.

Gentics Mesh Example for Fetching Content by Path using the WebRoot API

This functionality builds on top of using the nodes' segmentField property to build the path of a specific node. WebRoot paths of arbitrary depth can be created, in combination with organizing content hierarchically in terms of a content tree by specifying nodes to be containers for their child nodes. The WebRoot API endpoint uses this information to resolve a given path to a node UUID.

Using the WebRoot API it is possible to easily integrate Gentics Mesh with many known routing frameworks.

Framework Language Example

Silex

PHP

Blogpost

ExpressJS

JS

Blogpost

Vert.x

Java,JS,Ceylon

Blogpost

Lotus

Ruby

-

API endpoints

Description API endpoint

Load the node or the node’s binary data, which is located using the provided path.

GET /api/v1/:projectName/webroot/:path

Query content by path

A WebRoot path may consist of multiple path segments, each corresponding to a node within the content tree. The segmentField property from the schema is used to determine the node’s relevant field value.

Each segment of the URL must be URL-encoded. A node’s language variants must provide different path segment in order to guarantee unique paths.

Fetch node with UUID

Loading the node with the given UUID using API endpoint GET /api/v1/:projectName/nodes/:nodeUuid.

Query binary content by path

The WebRoot API, furthermore, directly supports delivering binary content using the fileName meta-data field of the binary field .

Fetch an image with UUID

Downloading a node’s binary field with the given name using API endpoint GET /api/v1/:projectName/nodes/:nodeUuid/binary/:fieldName.

Fetch an image with WebRoot path

When using a routing framework, in order to find out if a requested resource is binary data or JSON data you need to check the HTTP Content-Disposition response header. If it is set, it’s binary data.

Image manipulation by path

In case, the binary data is an image, the WebRoot API allows to directly perform image manipulation such as cropping and resizing.

Crop and resize an image with WebRoot path

Find out more about this topic in our blogpost about Gentics Mesh’s Image Manipulation API and Interface.

Properties

Query Parameters

Paging Parameters

Name Type Mandatory Description

page

number (default: 1)

false

Number of page to be loaded.

perPage

number (default: 25)

false

Number of elements per page.

Versioning Parameters

Name Type Mandatory Description

release

string

false

Specifies the release to be used for loading data. The latest project release will be used if this parameter is omitted.

version

string (default: draft)

false

Specifies the version to be loaded. Can either be published/draft or version number. e.g.: 0.1, 1.0, draft, published.

Node Parameters
Name Type Mandatory Description

lang

string

false

ISO 639-1 language tag of the language which should be loaded. Fallback handling can be applied by specifying multiple languages in a comma-separated list. The first matching language will be returned. If omitted or the requested language is not available then the defaultLanguage as configured in mesh.yml will be returned.

resolveLinks

string

false

The resolve links parameter can be set to either short, medium or full. Stored mesh links will automatically be resolved and replaced by the resolved webroot link. With the parameter set the path property as well as the languagesPath property (for available language variants) will be included in the response. Gentics Mesh links in any HTML-typed field will automatically be resolved and replaced by the resolved WebRoot path. No resolving occurs if no link has been specified.

Role Permission Parameters
Name Type Mandatory Description

role

string

false

The role query parameter take a UUID of a role and may be used to add permission information to the response via the rolePerm property which lists the permissions for the specified role on the element. This may be useful when you are logged in as admin but you want to retrieve the editor role permissions on a given node. Endpoint: /api/v1/:projectName/nodes?role=:roleUuid

Link resolving represents the counterpart of the WebRoot API - a node UUID can be resolved into a WebRoot path.

Gentics Mesh Example for automatically Resolving Links

Typically, editors create content including internal links to other nodes. When fetching content for your apps, however, Gentics Mesh will resolve these internal links for you and return a WebRoot path.

For example, {{mesh.link("2f2de9297c8143e8ade9297c8193e8fc", "en")}} will be transformed into /api/v1/demo/webroot/images/ford-gt.jpg when using the ?resolveLinks=full query parameter.

The ?resolveLinks query parameter defines if and how links are resolved:

  • off - links will not be resolved. This is the default.

  • full - the resolved links will contain the WebRoot prefix and project name (/api/v1/:projectName/webRoot/:path).

  • medium - the resolved links will contain the project name (/:projectName/:path).

  • short - will contain neither WebRoot prefix nor project name, just the path (:path).

The ?resolveLinks query parameter can be applied to all API endpoints returning nodes.

API endpoints

Description API endpoint

Get all nodes of a project and return a paged list response.

GET /api/v1/projectName/nodes

Get the node with the given UUID.

GET /api/v1/:projectName/nodes/:nodeUuid

Load the node or the node’s binary data, which is located using the provided path.

GET /api/v1/:projectName/webroot/:path

Get a navigation object for the provided node.

GET /api/v1/:projectName/nodes/:nodeUuid/navigation

Return a navigation for the node which is located using the given path.

GET /api/v1/:projectName/navroot/:path

In addition to the above, Gentics Mesh offers the /api/v1/utilities/linkResolver endpoint that can be used to resolve Gentics Mesh links within the posted text data. This is useful when resolving links for a preview page.

It’s necessary to send the content in which links should get resolved to the API endpoint in plain text or JSON. The query parameter ?resolveLinks is used to specify how links shall be resolved.

Valid links:

  • {{mesh.link("2f2de9297c8143e8ade9297c8193e8fc", "en")}}

  • {{mesh.link('2f2de9297c8143e8ade9297c8193e8fc', 'en')}}

  • {{mesh.link(\"2f2de9297c8143e8ade9297c8193e8fc\", \"en\")}}

  • {{mesh.link(2f2de9297c8143e8ade9297c8193e8fc, en)}}

  • {{mesh.link("2f2de9297c8143e8ade9297c8193e8fc")}} (link to default language)

  • {{mesh.link(2f2de9297c8143e8ade9297c8193e8fc)}} (link to default language)

Image Manipulation

Images can be resized and/or cropped by appending the image manipulation query parameters on the relevant API endpoints.

Fetch and Resize an Image with UUID

Endpoint: /api/v1/:projectName/nodes/:uuid/binary/:fieldname?width=220

Fetch and Crop an Image with WebRoot Path

It is also possible to use the image manipulation in combination with the WebRoot endpoint.

Endpoint: /api/v1/:projectName/webroot/:path?cropx=10&cropy=100&cropw=800&croph=400

It is mandatory to specify all four crop parameters when cropping an image.

Transform and Update an Image

Gentics Mesh also allows you to transform (i.e, crop and/or resize) and overwrite an image in a single step. The image manipulation parameters then are part of the request body.

Endpoint: POST /api/v1/:projectName/nodes/:uuid/binaryTransform/:fieldname

Request Body:

{
  "version" : {
    "number" : "1.0"
  },
  "language" : "en",
  "width" : 300
}

Image Manipulation Query Parameters

Name Type Mandatory Description

croph

number

false

Set image crop area height.

cropw

number

false

Set image crop area width.

cropx

number

false

Set image crop area start x coordinate.

cropy

number

false

Set image crop area start y coordinate.

height

number

false

Set image target height. The width will automatically be calculated if the height was omitted.

width

number

false

Set image target width. The height will automatically be calculated if the width was omitted.

Find out more about this topic in our blogpost about Gentics Mesh’s Image Manipulation API and Interface.

File Upload

Binary data can be attached to node binary fields. The /api/v1/nodes/:uuid/binary/:fieldName endpoint can be used to POST binary data and thus update the stored binary field.

This endpoint is accepting multipart/form-data, only.

It is required to specify the version and language within the update request. This is similar to regular node update requests in which these information must be added to the JSON object.

----------Geg2Oob
Content-Disposition: form-data; name="version"

1.0

----------Geg2Oob
Content-Disposition: form-data; name="language"

en

----------Geg2Oob
Content-Disposition: form-data; name="shohY6d"; filename="somefile.bin"
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary

fileData

----------Geg2Oob--

Configuration

Gentics Mesh stores all binary files on the filesystem. The default directory data/binaryfiles can be changed in the upload section of the main configuration file mesh.yml.

The upload limit can be configured in bytes using the uploadOptions.byteLimit setting.

For more information on available settings have a look at the administration guide.

Multi-Language

Gentics Mesh comes with multi-language support out of the box. In particular, a node serves as a container for one or more language variants. These language variants will store the actual content fields.

You can query individual language variants by appending the ?lang query parameter. The language json property within an update or create request will be used to identify which language variant should be created or updated.

Requests for nodes should contain the requested languages (as comma separated list)as query parameter:

Endpoint: /api/v1/:projectName/nodes/:uuid?lang=en,de

If the requested node is available in any of the languages, the response will contain the fields in that language (first language found).

Language Fallback

Gentics Mesh allows to configure a defaultLanguage in the main configuration file mesh.yml. This default language is used as a fallback in case:

  1. the lang query parameter has been omitted, or

  2. the requested content is not available in the specified language.

This fallback mechanism works when fetching nodes but also when requesting navigation objects or breadcrumb information.

In order to work properly, the fallback mechanism requires all nodes to have a language variant for the specified defaultLanguage.

Permissions

Permissions exist between roles and other elements (including other roles). By organizing users with groups and by assigning roles to groups, users inherit permissions on elements.

Most responses within Gentics Mesh will contain a list of permissions which may indicate that CRUD operations on the returned element are restricted in a way:

...
  "permissions" : {
    "create" : false,        //create other nodes
    "read" : false,          //read all versions of the node
    "update" : false,        //update the node
    "delete" : false,        //delete the node
    "publish" : false,       //publish or unpublish the node
    "readPublished" : true   //read the published version of the node
  }
...

The example above shows that the current user anonymous has the readPublish permission on the requested node, only. This means the user is allowed to read a published version of the node but not previous versions or a draft version of the requested element.

Furthermore the user is not allowed to

  • create other nodes

  • read a draft version of the node

  • update the requested node

  • delete the requested node

  • publish a draft version of the requested node, or unpublish a node.

Gentics Mesh by default returns the draft version of nodes. This means for supporting the anonymous user and public content, you need to add the ?version=published query parameter on all requests for nodes to avoid "Missing permissions on object" errors.
The publish and readPublish permissions are specifically available for node elements.

Following, we will discuss how to query, assign and revoke permissions in Gentics Mesh including the available API endpoints.

API endpoints

Description API endpoint

Read the user permissions on the element that can be located by the specified path.

GET /api/v1/users/:userUuid/permissions/:path

Load the permissions between given role and the targeted element.

GET /api/v1/roles/:roleUuid/permissions/:path

Set the permissions between role and the targeted element.

POST /api/v1/roles/:roleUuid/permissions/:path

Querying Permissions

There are dedicated API endpoints for querying permissions on elements.

The following example links, require prior authentication with user admin (credentials: admin/admin). Please refer to the authentication section to learn about the different authentication mechanisms provided by Gentics Mesh.

The /api/v1/roles/:roleUuid/permissions/:path endpoint can be used to query a role’s permission on a specific element or set of elements.

For example, the authenticated admin user is able to find out the configured permissions for role anonymous on node fc3c85be82584ae2bc85be82588ae2b0:

POST http://localhost:8080/api/v1/roles/292abe389d434b1eaabe389d430b1ee0/permissions/projects/217f8c981ada4642bf8c981adaa642c3/nodes/88fac3fbc61041c1bac3fbc610d1c182

{
    "create": false,
    "read": false,
    "update": false,
    "delete": false,
    "publish": false,
    "readPublished": true
}

Alternatively, the endpoint /api/v1/users/:userUuid/permissions/:path provides a shortcut for querying permissions for specific users directly, e.g., for user anonymous, which is essentially inheriting all permissions from role anonymous.

Assigning & Revoking Permissions

The /api/v1/roles/:roleUuid/permissions API endpoint can be used to assign or revoke permissions to/from a role.

Furthermore, this endpoint can also be used to apply recursive permissions. It is important to note that permissions can be applied to individual elements and onto a set of elements which is identified by the endpoint name (e.g.: /group and /groups).

For newly created objects CRUD permissions are assigned to those roles that would be able to also create the object in the first place. By this we ensure that roles that would also be able to create the object are now able to invoke CRUD on the newly created object.

Example:

  • User John is assigned to Role A. Role A grants him to create a new child Node in a parent Node.

  • User Mary is assigned to Role B. Role B grants her to also create a new child Node in the same parent Node.

  • When John creates a new Node the permission system identifies Role B as a role that would also be able to create the object. Therefore CRUD permissions are assigned in between Role A and B and the newly created object.

Users

Recursive permission changes on /users will also affect all listed users.

Element Permission Description

/api/v1/users

Create

New users can be created.

/api/v1/users

Read

Not used

/api/v1/users

Update

Not used

/api/v1/users

Delete

Not used

/api/v1/users

Read Published

Not used

/api/v1/users

Publish

Not used

Recursive permission changes on /users/:uuid have no effect on referenced elements such as node references.

Element Permission Description

/api/v1/users/:uuid

Create

Not used

/api/v1/users/:uuid

Read

User can be read.

/api/v1/users/:uuid

Update

User can be updated.

/api/v1/users/:uuid

Delete

User can be deleted.

/api/v1/users/:uuid

Read Published

Not used

/api/v1/users/:uuid

Publish

Not used

Groups

Recursive permission changes on /groups will affect all groups.

Element Permission Description

/api/v1/groups

Create

New roles can be created.

/api/v1/groups

Read

Not used

/api/v1/groups

Update

Not used

/api/v1/groups

Delete

Not used

/api/v1/groups

Read Published

Not used

/api/v1/groups

Publish

Not used

Recursive permission changes on /groups/:uuid will also affect users of the group but not roles that are linked to the group.

Element Permission Description

/api/v1/groups/:uuid

Create

Not used

/api/v1/groups/:uuid

Read

Group can be read.

/api/v1/groups/:uuid

Update

Group can be updated.

/api/v1/groups/:uuid

Delete

Group can be deleted.

/api/v1/groups/:uuid

Read Published

Not used

/api/v1/groups/:uuid

Publish

Not used

Roles

Element Permission Description

/api/v1/roles

Create

New roles can be created.

/api/v1/roles

Read

Not used

/api/v1/roles

Update

Not used

/api/v1/roles

Delete

Not used

/api/v1/roles

Read Published

Not used

/api/v1/roles

Publish

Not used

Recursive permission changes on /roles/:uuid have no effect.

Element Permission Description

/api/v1/roles/:uuid

Create

Not used

/api/v1/roles/:uuid

Read

Role can be read.

/api/v1/roles/:uuid

Update

Role can be updated.

/api/v1/roles/:uuid

Delete

Role can be deleted.

/api/v1/roles/:uuid

Read Published

Not used

/api/v1/roles/:uuid

Publish

Not used

Schemas

Recursive permission changes on /schemas will also affect schemas.

Element Permission Description

/api/v1/schemas

Create

New schemas can be created.

/api/v1/schemas

Read

Not used

/api/v1/schemas

Update

Not used

/api/v1/schemas

Delete

Not used

/api/v1/schemas

Read Published

Not used

/api/v1/schemas

Publish

Not used

Recursive permission changes on /schemas/:uuid have no effect on referenced elements.

Element Permission Description

/api/v1/schemas/:uuid

Create

Not used

/api/v1/schemas/:uuid

Read

The schema can be read. Read permission on the schema is also needed to be able to create new nodes that are based upon the schema.

/api/v1/schemas/:uuid

Update

The schema can be updated.

/api/v1/schemas/:uuid

Delete

The schema can be deleted.

/api/v1/schemas/:uuid

Read Published

Not used

/api/v1/schemas/:uuid

Publish

Not used

Microschemas

Recursive permission changes on /schemas will also affect schemas.

Element Permission Description

/api/v1/microschemas

Create

New microschemas can be created.

/api/v1/microschemas

Read

Not used

/api/v1/microschemas

Update

Not used

/api/v1/microschemas

Delete

Not used

/api/v1/microschemas

Read Published

Not used

/api/v1/microschemas

Publish

Not used

Recursive permission changes on /microschemas/:uuid have no effect on referenced elements.

Element Permission Description

/api/v1/microschemas/:uuid

Create

Not used

/api/v1/microschemas/:uuid

Read

The microschema can be read.

/api/v1/microschemas/:uuid

Update

The microschema can be updated.

/api/v1/microschemas/:uuid

Delete

The microschema can be deleted.

/api/v1/microschemas/:uuid

Read Published

Not used

/api/v1/microschemas/:uuid

Publish

Not used

Projects

Recursive permission changes on /projects will also affect all projects and those elements.

Element Permission Description

/api/v1/projects

Create

Create new projects.

/api/v1/projects

Read

Not used

/api/v1/projects

Update

Not used

/api/v1/projects

Delete

Not used

/api/v1/projects

Read Published

Not used

/api/v1/projects

Publish

Not used

Recursive permission changes on /projects/:uuid will also affect schemas, tagfamilies (and tags), nodes and subnodes.

Element Permission Description

/api/v1/projects/:uuid

Create

Not used

/api/v1/projects/:uuid

Read

Project can be read.

/api/v1/projects/:uuid

Update

Project can be updated.

/api/v1/projects/:uuid

Delete

Project can be deleted.

/api/v1/projects/:uuid

Read Published

Affected node publish versions can be read.

/api/v1/projects/:uuid

Publish

Affected node can be published.

Tag Families

Recursive permission changes on /projects/:uuid/tagFamilies will also all tagfamiles and those tags.

Element Permission Description

/api/v1/projects/:uuid/tagFamilies

Create

Create new tag families.

/api/v1/projects/:uuid/tagFamilies

Read

Not used

/api/v1/projects/:uuid/tagFamilies

Update

Not used

/api/v1/projects/:uuid/tagFamilies

Delete

Not used

/api/v1/projects/:uuid/tagFamilies

Read Published

Not used

/api/v1/projects/:uuid/tagFamilies

Publish

Not used

Recursive permission changes on /projects/:uuid/tagFamilies/:uuid will also affect tags.

Element Permission Description

/api/v1/projects/:uuid/tagFamilies/:uuid

Create

Tags can be created within the tag family.

/api/v1/projects/:uuid/tagFamilies/:uuid

Read

Tag family can be read.

/api/v1/projects/:uuid/tagFamilies/:uuid

Update

Tag family can be updated.

/api/v1/projects/:uuid/tagFamilies/:uuid

Delete

Tag family can be deleted.

/api/v1/projects/:uuid/tagFamilies/:uuid

Read Published

Not used

/api/v1/projects/:uuid/tagFamilies/:uuid

Publish

Not used

Tags

Recursive permission on /api/v1/projects/:uuid/tagFamilies/:uuid/tags changes have no effect.

Element Permission Description

/api/v1/:projectName/tagFamilies/:uuid/tags

Create

Create new tags.

/api/v1/:projectName/tagFamilies/:uuid/tags

Read

Not used

/api/v1/:projectName/tagFamilies/:uuid/tags

Update

Not used

/api/v1/:projectName/tagFamilies/:uuid/tags

Delete

Not used

/api/v1/:projectName/tagFamilies/:uuid/tags

Read Published

Not used

/api/v1/:projectName/tagFamilies/:uuid/tags

Publish

Not used

Recursive permission changes on /projects/:uuid/tagFamilies/:uuid/tags/:uuid have no effect.

Element Permission Description

/api/v1/:projectName/tags/:uuid

Create

Not used

/api/v1/:projectName/tags/:uuid

Read

Tag can be read.

/api/v1/:projectName/tags/:uuid

Update

Tag can be updated.

/api/v1/:projectName/tags/:uuid

Delete

Tag can be deleted.

/api/v1/:projectName/tags/:uuid

Read Published

Not used

/api/v1/:projectName/tags/:uuid

Publish

Not used

Nodes

Recursive permission changes on /:projectName/nodes/:uuid will also affect children of the node.

Element Permission Description

/api/v1/:projectName/nodes

Create

Not used

/api/v1/:projectName/nodes

Read

Not used

/api/v1/:projectName/nodes

Update

Not used

/api/v1/:projectName/nodes

Delete

Not used

/api/v1/:projectName/nodes

Read Published

Not used

/api/v1/:projectName/nodes

Publish

Not used

Recursive permission changes on /:projectName/nodes/:uuid will also affect children of the node.

Element Permission Description

/api/v1/:projectName/nodes/:uuid

Create

Create new nodes within the node

/api/v1/:projectName/nodes/:uuid

Read

Node can be read.

/api/v1/:projectName/nodes/:uuid

Update

Node can be updated.

/api/v1/:projectName/nodes/:uuid

Delete

Node can be deleted.

/api/v1/:projectName/nodes/:uuid

Read Published

Published version can be read.

/api/v1/:projectName/nodes/:uuid

Publish

Node can be published.

Releases

Element Permission Description

/api/v1/:projectName/releases

Create

Releases can be created.

/api/v1/:projectName/releases

Read

Not used

/api/v1/:projectName/releases

Update

Not used

/api/v1/:projectName/releases

Delete

Not used

/api/v1/:projectName/releases

Read Published

Not used

/api/v1/:projectName/releases

Publish

Not used

Element Permission Description

/api/v1/:projectName/releases/:uuid

Create

Nod used

/api/v1/:projectName/releases/:uuid

Read

Release can be read.

/api/v1/:projectName/releases/:uuid

Update

Release can be updated.

/api/v1/:projectName/releases/:uuid

Delete

Permission does not apply. Releases can’t be deleted.

/api/v1/:projectName/releases/:uuid

Read Published

Not used

/api/v1/:projectName/releases/:uuid

Publish

Not used

Versioning

In order to understand the concept of versioning in Gentics Mesh it is important to remember that nodes are containers for language variants (see Multi-Language). The language variant of a node contains the fields and thus stores all the content.

Versioning within Gentics Mesh only applies to language variants and their referenced fields. Other elements such as users, groups, roles, permissions and even nodes are not versioned.

Various content management tasks will have different effects for versioning in Gentics Mesh. Some of them create versions, others don’t. Following, we go through all of these actions which involve versioning.

At the moment it is not possible to delete older versions.

Node Creation

Once a node has been created the initial version 0.1 will be assigned to its language variant.

Node Updates

Updating a node’s language variant may create a minor version 0.2 of that language variant if changes have been detected within the posted request fields.

No Locks:

It is not required to handle locks in Gentics Mesh. Instead it is required to specify the version in the update request which identifies the version on which the update request was based upon.

Conflict detection:

Gentics Mesh will check whether new versions have been created in the meanwhile. Long running edit operations or multiple concurrent editors may create additional versions.

The detected changes will be compared automatically in order to determine whether the current update request causes a conflict with a newer edit request. Gentics Mesh will return a response which contains information about the conflict in those cases. Other update operations which do not cause a conflict will be stored and the changed fields will be updated.

The latest version which was created using an update request is called the draft version. Only a single draft version per language variant exists.

Publishing Nodes

Node language variants can be published and taken offline. This is particularly useful if you want to first work on a draft, then review it and publish it at a later point in time.

Publishing requires a POST request on the /api/v1/:projectName/nodes/:uuid/published endpoint, which will publish all language variants of the node. It is also possible to just publish specific language variants with dedicated POST requests on /api/v1/:projectName/nodes/:uuid/languages/:languageTag/published.

Gentics Mesh will automatically create a new major version when publishing a node language variant (e.g.: 1.0, 2.0). The draft reference will also be updated to point to the major version, e.g. 1.0.

Furthermore, it is possible to retrieve information about the published status via a GET request on /api/v1/:/nodes/:uuid/published.

Publishing node language variants requires the user to be assigned to a group with a role which provides the publish permission.
{
  "availableLanguages" : {
    "de" : {
      "published" : false,
      "version" : "0.4"
    },
    "en" : {
      "published" : true,
      "version" : "3.0",
      "publisher" : {
        "firstName" : "Joe",
        "lastName" : "Doe",
        "uuid" : "3078151ea9d94769b8151ea9d94769ab"
      },
      "publishDate" : "2017-09-18T12:20:54.381Z"
    },
    "fr" : {
      "published" : false,
      "version" : "5.2"
    }
  }
}
It is not possible to publish a specific version. Publish always affects the latest draft version of the language variant.

Taking Nodes Offline

Similarly to publishing, the language variants of a node can be taken offline via a DELETE request on /api/v1/:projectName/nodes/:uuid/published. E.g., taking a specific node language variant with version 1.0 offline using DELETE /api/v1/:projectName/nodes/:uuid/languages/:languageTag/published will just change the node’s publish state. Version 1.0 will still be available.

Taking node language variants offline requires the user have publish permissions on the node.

Reading Nodes

It is possible to fetch older versions by specifying the ?version query parameter. Similarly, the published version of a node language variant can also be loaded using the parameter ?version=published or the draft version via ?version=draft.

Gentics Mesh by default returns the draft version of nodes. This means for supporting the anonymous user and public content, you need to add the ?version=published query parameter on all requests for nodes to avoid "Missing permissions on object" errors.
Reading published nodes requires the user to be assigned to a role which grants the readPublished permission.

Content Releases

So far we learned that node language variants can be versioned and published. Additionally Mesh versioning provides a powerful concept we call Releases. A release is very similar to branches in a versioning control system.

Releases can be used to restructure your nodes and change the contents within a specific release without affecting a different release which provides a different structure/content.

Structural references for nodes always contain release information. This applies to parent/child relationship or taggings, publish states of nodes. This way releases are completely isolated from each other.

It is currently not possible to migrate from one release to another. Nodes of releases can’t be automatically merged to other releases.

Typical usecases are:

  • Updating an existing application installation which uses Gentics Mesh to a new version. The new application version requires new schema versions. By creating a release and migrating the nodes to the new release (new schema versions), it is possible to serve content for both application versions. Each application versions chooses the correct release for getting nodes.

  • Schema versions must be assigned to the release. Each project can have multiple releases. An initial release will automatically be created when creating a project.

All operations to nodes can be scoped to a specific release by adding the ?release=name query parameter. If omitted the latest release will be used to execute the operation.

Implementations which use mesh should always reference a specific release. Otherwise the document structure could change without the implementation being aware of these changes.

Creating a Release

A release requires an unique name. Existing nodes within the project will automatically be migrated into the release. Please note the started node migration will be processed asynchronously and thus not all nodes may be directly accessible within the scope of the release.

This migration is different from a schema version migration. The release node migration just takes care of making all nodes from the previous release available in the newly created release. Unlike the schema migration the node migration will not create new language variant versions.

You can use the eventbus bridge or the dedicated /api/v1/admin/status/migrations endpoint to query the migration status. The migrated JSON property within the release response also indicates whether the node migration has been completed.

Note: Migrated nodes will still have the same uuid as before.

Updating a Release

A release can be renamed and new schema/microschema versions can be assigned to it.

Renaming is useful if you want to change your development release to be the current production release.

Assigning schema versions to the release via a PUT request to /api/v1/:projectName/releases/:uuid/schemas will automatically trigger a schema migration of the affected nodes language variants within the release.

{
  "schemas" : [ {
    "name" : "content",
    "uuid" : "e893d0b52eaf4dac93d0b52eaf4dacd2",
    "version" : "1.0"
  }, {
    "name" : "folder",
    "uuid" : "6f495ed6fe944154895ed6fe9401543f",
    "version" : "1.0"
  }, {
    "name" : "binary-data",
    "uuid" : "2d657a4706344bf6a57a4706349bf6ed",
    "version" : "1.0"
  } ]
}

It is also possible to assign microschemas via a PUT request to /api/v1/:projectName/releases/:uuid/microschemas to the release.

{
  "microschemas" : [ {
    "name" : "vcard",
    "uuid" : "a077d5c552c3464eb7d5c552c3264eb2",
    "version" : "2.0"
  }, {
    "name" : "geolocation",
    "uuid" : "07039b174387413e839b174387513e50",
    "version" : "1.0"
  } ]
}

All nodes which reference the release via the updated schema version will automatically be migrated to use the newer schema version. Please note the started schema migration will be processed asynchronously and thus not all node language variants may be directly accessible within the scope of the release.

The migration will create new versions for the affected node language variants.

It is note worthy that updating a schema and thus creating new schema version will not automatically affect the release. Each schema update created a new schema version. This new version must first be assigned to the release.

Deleting a Release

At the moment it is not possible to delete a release.

Moving Nodes

Releases enable Gentics Mesh to setup multiple content project tree structures. Moving nodes can be scoped to a specific release using the ?release request parameter. The project’s initial release will be used to execute the move operation if no release has been selected.

Tagging Nodes

The tag operation is also scoped to a specific release. This way new tags can be assigned to your nodes for a specific release without affecting the taggings of nodes within an older release.

Tags and tag families are not versioned. Deleting a tag will remove the tag from all nodes that previously referenced this tag.
Taggings to nodes are not versioned.

Deleting Nodes

Deleting nodes is also release specific. Deleting a node via DELETE to /api/v1/:projectName/node/:uuid?release=winter2016 will delete the node and all its sub nodes from the winter2016 release. The node will be completely removed from the system if no more language variants are referenced within any release.

It is also possible to just delete a specific language variant via DELETE to /api/v1/:projectName/node/:uuid/languages/en?release=winter2016 from release winter2016.

Updating Nodes

Releases are completely isolated from each other as explained earlier. This also applies to a node’s language variant versions.

Example:

  • Create release summer2016

  • Create node with language variant de at version 1.0 in release summer2016

  • Create release winter2016

  • Update previously created node in release summer2016 and thus create version 1.1

Release summer2016 will reference node language variant 1.1 and winter2016 will still reference version 1.0 since the winter2016 release was created at the specific point of time in which the language variant in release summer2016 was still at version 1.0.

It is currently not possible to migrate 1.1 from summer2016 to winter2016.

Additionally creating new nodes in summer2016 will not be available in release winter2016.

Permissions

Permissions are not release specific.

Search requests are handled by the /api/v1/search or /api/v1/:projectName/search endpoints.

Elasticsearch is used in order to provide the search functionality. This way elasticsearch queries can be posted to the search endpoints.

The JSON format of stored documents within the elasticsearch differ from the JSON format that is returned via regular Gentics Mesh endpoints. Thus it is important to know the elasticsearch document format when building an elasticsearch query. Below is a list of various example documents.

It is not possible to search for specific individual versions. Instead only published and draft versions per release are stored in the search index.

Users

Endpoint: /api/v1/search/users

{
  "uuid" : "36311264d71740a4b11264d71760a44d",
  "creator" : {
    "uuid" : "9b72e4fc99ba4162b2e4fc99ba216210"
  },
  "created" : null,
  "editor" : {
    "uuid" : "9b72e4fc99ba4162b2e4fc99ba216210"
  },
  "edited" : null,
  "username" : "joe1",
  "emailaddress" : "joe1@nowhere.tld",
  "firstname" : "Joe",
  "lastname" : "Doe",
  "groups" : {
    "name" : [ "editors", "superEditors" ],
    "uuid" : [ "209868251ba94d179868251ba9fd1701", "be7c3ea28b384676bc3ea28b38467699" ]
  }
}

Groups

Endpoint: /api/v1/search/groups

{
  "name" : "adminGroup",
  "uuid" : "cecd016fa0894cd78d016fa0890cd73e",
  "creator" : {
    "uuid" : "d960322369e24552a0322369e2855206"
  },
  "created" : null,
  "editor" : {
    "uuid" : "d960322369e24552a0322369e2855206"
  },
  "edited" : null
}

Roles

Endpoint: /api/v1/search/roles

{
  "name" : "adminRole",
  "uuid" : "7cc63f32bda549b2863f32bda5b9b2c6",
  "creator" : {
    "uuid" : "faefd5e18f944a00afd5e18f94ba00d5"
  },
  "created" : null,
  "editor" : {
    "uuid" : "faefd5e18f944a00afd5e18f94ba00d5"
  },
  "edited" : null
}

Nodes

Endpoint: /api/v1/search/nodes

{
  "uuid" : "9db0520a63c34a99b0520a63c30a9931",
  "editor" : {
    "uuid" : "8e84f291cac2429f84f291cac2729fce"
  },
  "edited" : "1970-01-01T00:00:00Z",
  "creator" : {
    "uuid" : "8e84f291cac2429f84f291cac2729fce"
  },
  "created" : "1970-01-01T00:00:00Z",
  "project" : {
    "name" : "dummyProject",
    "uuid" : "7ce17f46b1504e9ca17f46b150ee9ccf"
  },
  "tags" : {
    "name" : [ "green", "red" ],
    "uuid" : [ "fa91e074e866497f91e074e866597fae", "ab367a937bec47ddb67a937bec77ddf3" ]
  },
  "tagFamilies" : {
    "colors" : {
      "uuid" : "844169b1810b4f2f8169b1810b0f2f28",
      "tags" : [ {
        "name" : "green",
        "uuid" : "fa91e074e866497f91e074e866597fae"
      }, {
        "name" : "red",
        "uuid" : "ab367a937bec47ddb67a937bec77ddf3"
      } ]
    }
  },
  "parentNode" : {
    "uuid" : "4996e323b01043ad96e323b010b3ad8f"
  },
  "language" : "de",
  "schema" : {
    "name" : "content",
    "uuid" : "3ae5b0439da9497aa5b0439da9c97a63",
    "version" : null
  },
  "fields" : {
    "date" : 1505737254,
    "string" : "The name value",
    "htmlList" : [ "some<b>html", "some<b>html", "some<b>html" ],
    "nodeList" : [ "1f224d6d3548409aa24d6d3548909a9e", "1f224d6d3548409aa24d6d3548909a9e", "1f224d6d3548409aa24d6d3548909a9e" ],
    "number" : 0.146,
    "node" : "1f224d6d3548409aa24d6d3548909a9e",
    "boolean" : true,
    "stringList" : [ "The name value", "The name value", "The name value" ],
    "micronode" : {
      "microschema" : {
        "name" : null,
        "uuid" : null
      },
      "fields-null" : {
        "latitude" : 16.373063840833,
        "longitude" : 16.373063840833
      }
    },
    "html" : "some<b>html",
    "numberList" : [ 0.146, 0.146, 0.146 ],
    "booleanList" : [ "true", "true", "true" ],
    "dateList" : [ 1505737254, 1505737254, 1505737254 ]
  },
  "displayField" : {
    "key" : "string",
    "value" : null
  }
}

Search nodes by schema name

Listed below is an example search query which can be posted to /api/v1/search/nodes in order to find all nodes across all projects which were created using the content schema. The found nodes will be sorted ascending by creator.

{
  "sort" : {
     "created" : { "order" : "asc" }
  },
  "query":{
    "bool" : {
      "must" : {
        "term" : { "schema.name" : "content" }
       }
    }
  }
}

Search nodes by micronode field values

Find all nodes which have a micronode list field (vcardlist) that contain at least one micronode which contains the two string fields (firstName, lastName) with the values ("Joe", "Doe"):

{
  "query": {
    "nested": {
      "path": "fields.vcardlist",
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "fields.vcardlist.fields.firstName": "Joe"
              }
            },
            {
              "match": {
                "fields.vcardlist.fields.lastName": "Doe"
              }
            }
          ]
        }
      }
    }
  }
}

Search nodes which are tagged 'Solar' and 'Blue'

The tags field is a nested field and thus a nested query must be used to match the two tags. Please note that you need to use match_phrase because you want to match the whole tag name. Using match would cause elasticsearch to match any of trigram found within the tag name value.

{
  "query": {
    "nested": {
      "path": "tags",
      "query": {
        "bool": {
          "must": [
            {
              "match_phrase": {
                "tags.name": "Solar"
              }
            },
            {
              "match_phrase": {
                "tags.name": "Blue"
              }
            }
          ]
        }
      }
    }
  }
}

Projects

Endpoint: /api/v1/search/projects

{
  "name" : "dummyProject",
  "uuid" : "0ee2e7ec82e74d6fa2e7ec82e71d6f18",
  "creator" : {
    "uuid" : "7cc6c0528ea44dbd86c0528ea4fdbd4d"
  },
  "created" : null,
  "editor" : {
    "uuid" : "7cc6c0528ea44dbd86c0528ea4fdbd4d"
  },
  "edited" : null
}

Tags

Endpoint: /api/v1/search/tags

{
  "name" : "red",
  "uuid" : "0e6ad4c3927849a6aad4c3927869a6cd",
  "creator" : {
    "uuid" : "6933f701b9754449b3f701b975c449b1"
  },
  "created" : null,
  "editor" : {
    "uuid" : "6933f701b9754449b3f701b975c449b1"
  },
  "edited" : null,
  "tagFamily" : {
    "name" : "colors",
    "uuid" : "52cfe5a3a6e64df78fe5a3a6e60df7ae"
  },
  "project" : {
    "name" : "dummyProject",
    "uuid" : "375d7dfa7e4143759d7dfa7e4113754a"
  }
}

Tag Families

Endpoint: /api/v1/search/tagFamilies

{
  "name" : "colors",
  "uuid" : "0cb0ad90341c4f58b0ad90341cff587e",
  "creator" : {
    "uuid" : "09232889ba6e4a22a32889ba6e4a22a3"
  },
  "created" : null,
  "editor" : {
    "uuid" : "09232889ba6e4a22a32889ba6e4a22a3"
  },
  "edited" : null,
  "tags" : {
    "name" : [ "red", "green" ],
    "uuid" : [ "af8c21feef554fe88c21feef550fe882", "6818c6a6c405440b98c6a6c405040b55" ]
  },
  "project" : {
    "name" : "dummyProject",
    "uuid" : "96bdb52f91d94879bdb52f91d97879b4"
  }
}

Schemas

Endpoint: /api/v1/search/schemas

{
  "name" : "content",
  "description" : "Content schema",
  "uuid" : "084de2cbae0d4bc38de2cbae0d9bc317",
  "creator" : {
    "uuid" : "d57546dcb97a4e15b546dcb97a6e15a2"
  },
  "created" : null,
  "editor" : {
    "uuid" : "d57546dcb97a4e15b546dcb97a6e15a2"
  },
  "edited" : null
}

Microschemas

Endpoint: /api/v1/search/microschemas

{
  "uuid" : "c242ea4bd590462182ea4bd590a621e7",
  "creator" : {
    "uuid" : "936b50e0a9574733ab50e0a95717339e"
  },
  "created" : null,
  "editor" : {
    "uuid" : "936b50e0a9574733ab50e0a95717339e"
  },
  "edited" : null,
  "name" : "geolocation"
}

Paging

The paging query parameters are perPage and page . It is important to note that page is 1-based and perPage can be set to 0 in order to just retrieve a count of elements.

Preview Handling

The Gentics Mesh User Interface provides a preview button when editing nodes. A post request to a configureable url is being dispatched when the button is triggered. The post request will contain the node JSON data of the current editing state. This way a preview page can be easily rendered by custom frontend implementations.

Password Recovery

A user who lost his password is able to recover it using a reset token. This token, typically, is issued by a user or service having permissions to create new users. The /api/v1/users/:userUuid/reset_token endpoint will return a token code which then can be passed along to an email service sending a recovery email to the user including named token.

A token is valid for 30 minutes and will be invalidated once it has been used.

The user can use this token to update his user record by issuing a POST request to the /api/v1/users/:userUuid?token=TOKENCODE endpoint. E.g., this can be done by presenting the user a form for updating his password. This works even if the user is not authenticated.

Schema & Microschema Migration

Gentics Mesh provides a changelog like system in order to apply and keep track of schema changes. A schema change may be a single change that adds a new field to the schema or a change which updates the schema properties.

Gentics Mesh supports the following change operations:

Operation: addfield

Properties Description

after

Name of the field after which the new field should be inserted

field

Name of the field that should be added

type

Type of the field

listType

Optional list type

{
  "operation" : "ADDFIELD",
  "properties" : {
    "field" : "fieldToBeAdded",
    "label" : "Field Label Value",
    "after" : "firstField",
    "type" : "list",
    "listType" : "html"
  }
}

Operation: removefield

Properties Description

field

Name of the field to be removed

{
  "operation" : "REMOVEFIELD",
  "properties" : {
    "field" : "fieldToBeRemoved"
  }
}

Operation: changefieldtype

Properties Description

field

Name of the field to be modified

type

New field type

listType

(Only applies for lists) New list type

{
  "operation" : "CHANGEFIELDTYPE",
  "properties" : {
    "field" : "fieldToBeChanged",
    "type" : "html"
  }
}

Operation: updatefield

Properties Description

field

Field to be updated

label

New field label

{
  "operation" : "UPDATEFIELD",
  "properties" : {
    "field" : "fieldToBeUpdated",
    "name" : "newName"
  }
}

Operation: updateschema

Properties Description

description

New schema description

order

Array of strings that contains the field order

displayFieldname

New displayFieldname value of the schema

segmentFieldname

New segmentFieldname value of the schema

container

New container flag of the schema

{
  "operation" : "UPDATESCHEMA",
  "properties" : {
    "container" : "true",
    "segmentFieldname" : "newSegmentField",
    "displayFieldname" : "newSegmentField",
    "description" : "new description",
    "label" : "new label"
  }
}

Operation: updatemicroschema

Properties Description

description

New microschema description

{
  "operation" : "UPDATEMICROSCHEMA",
  "properties" : {
    "description" : "new description",
    "label" : "new label"
  }
}

Each change may also provide a migration script. The migration script can be used to modify nodes that were affected by the migration.

Typical usecases for migration scripts are for example dynamic field removal or even custom reformatting of field data. It is also possible to split a single field value into values for two new fields.

The /api/v1/schemas/:uuid/diff and /api/v1/microschemas/:uuid/diff endpoints can be used to generate a list of changes by comparing the stored and posted schema.

This list of changes can be modified and posted to /api/v1/schemas/:uuid/changes for schemas or /api/v1/microschemas/:uuid/changes for microschemas. The posted list of changes will be validated and stored when valid. A schema migration process will be started which runs in the background.

The SockJS compliant /api/v1/eventbus endpoint can be used to register to migration specific messages.

Additionally to websocket it is possible to query whether a migration is running via the /api/v1/admin/status/migrations endpoint.

Sending a schema to /api/v1/schemas:uuid using the PUT method will conveniently combine the diff generation and invocation of the schema migration.

Please note that by default conflicting data will be removed and this action can only be avoided by specifying a custom migration script.

Custom Migration Scripts

Sometimes it is desired to overwrite the default migration behaviour.

The following migration script converts the number value from field node.fields[fieldname] into a ISO-8601 date string which is then stored within the node.fields[fieldname] field.

function migrate(node, fieldname, convert) {
    node.fields[fieldname] = new Date(new Date(node.fields[fieldname]).getTime() + 864000).toISOString();
    return node;
}

Migration scripts also allow you to split up a field value into two different fields.

function migrate(node, fieldname, convert) {
    node.fields["fieldA"] = "First field set";
    node.fields["fieldB"] = "Second field set";
    return node;
}

The provided converter can be used to convert in between field types. This converter will be used if no custom migration script was specified.

function migrate(node, fieldname, convert) {
    var stringValue = convert.toString(node.fields[fieldname]);

    // It is important to use the Java.from method to convert the java list object into a number array.
    var numberArray    = Java.from(convert.toNumberList(node.fields[fieldname]));
    var micronodeArray = Java.from(convert.toMicronodeList(node.fields[fieldname]));
    var dateArray      = Java.from(convert.toDateList(node.fields[fieldname]));
    var booleanArray   = Java.from(convert.toBooleanList(node.fields[fieldname]));

    var numberValue    = convert.toNumber(node.fields[fieldname]);
    var nodeValue      = convert.toNode(node.fields[fieldname]);
    var micronodeValue = convert.toMicronode(node.fields[fieldname]);
    var dateValue      = convert.toDate(node.fields[fieldname]);
    var booleanValue   = convert.toBoolean(node.fields[fieldname]);
    var binaryValue    = convert.toBinary(node.fields[fieldname]);

    // Delete the field
    delete node.fields[fieldname];
    return node;
}

Finally the changes can be applied by sending the request to /api/v1/schemas/:uuid/changes.

{
  "changes" : [ {
    "operation" : "ADDFIELD",
    "properties" : {
      "field" : "listFieldToBeAddedField",
      "label" : "Field Label Value",
      "type" : "list",
      "listType" : "html"
    }
  }, {
    "operation" : "CHANGEFIELDTYPE",
    "properties" : {
      "field" : "fieldToBeUpdated",
      "type" : "string"
    }
  }, {
    "operation" : "REMOVEFIELD",
    "properties" : {
      "field" : "fieldToBeRemoved"
    }
  }, {
    "operation" : "UPDATEFIELD",
    "migrationScript" : "function migrate(node, fieldname) {node.fields[fieldname] = new Date(new Date(node.fields[fieldname]).getTime() + 864000).toISOString(); return node;}",
    "properties" : {
      "field" : "fieldToBeUpdated",
      "displayFieldname" : "newDisplayField",
      "label" : "newLabel"
    }
  }, {
    "operation" : "UPDATESCHEMA",
    "properties" : { }
  } ]
}

Executing migrations

Migrations can potentially affect a huge amount of nodes depending on the size of your project. As such the migration could take some time to complete. This is why we designed migrations in ways that they can be executed asynchronously. Various operations in Gentics Mesh (eg. Schema update, assigning versions to releases, creating releases) may trigger migrations. Before the migration is being executed a job is added to the job queue. You can view the queue via the /api/v1/admin/jobs endpoint. These jobs will be processed and execute the actual migration.

By default updating a schema will create a new schema version and the nodes will be migrated to that new version. If you want to deferre this operation you can set the updateAssignedReleases query parameter to false when updating a schema/microschema. This leads to a new schema version being created but the version would not be linked to your current release and no migration would be invoked.

Once a job has been queued and a migration has been invoked the status can be checked via the /api/v1/admin/status/migrations endpoint.

A job will only be removed from the job list when the job completed without any error. Erroneous jobs will stay in the job list. This way interrupted migrations can be picked up and executed once again.

Intermediate errors may cause a job to fail. In those cases it is possible to reset the error flag of a job by executing DELETE /api/v1/admin/jobs/:jobUuid/error. The job can run again once the error flag has been cleared. It is possible to invoke POST /api/v1/admin/processJobs to trigger a manual event which will start the job processing.

Jobs which keep failing can be permanently removed from the job queue via the DELETE /api/v1/admin/jobs/:jobUuid endpoint. Please note that it is only possible to remove jobs which have failed. Jobs which don’t fail will automatically be removed from the list.

Eventbus Bridge & Websocket

The /api/v1/eventbus endpoint allows clients to access the eventbus. This may be useful if you want to react on specific events. Currently only schema migration specific events are handled via this endpoint but more will follow.

The endpoint is SockJS compliant. It is also possible to access the websocket directly via: /api/v1/eventbus/websocket.

Eventname Description

mesh.migration

Receive node and micronode migration specific events

Clustering

Clustering is described in detail in our dedicated clustering documentation.