
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.
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.
: if true, nodes can contain child nodes and build a node tree.container
: 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.segmentField
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:
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
property set to container
, thus allowing nodes of type category to have child nodes. The schema’s true
is specified to be the segmentField
field. Thus, the resulting value for the slug
property of node Automobiles is path
./automobiles
The schema vehicle has the
property set to container
. The schema’s false
is again specified to be the segmentField
field. Thus, the resulting value for the slug
property of node Ford GT is path
./automobiles/ford-gt
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
is used to build the path of a specific node. According to the nodes’ schemas in our example, the path segmentField
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./automobiles/ford-gt
The
property as well as the path
property (for available language variants) of a node can be queried using the languagesPath
endpoint together with the query parameter /api/v1/projectName/nodes/:nodeUuid
. Alternatively, the WebRoot API can be used resolveLinks
For more details see the documentation on node and WebRoot API, respectively./api/v1/:projectName/webroot/:path
You can also specify dedicated paths for nodes using the
schema property. You can add string or string list fields to your schema and list them via the urlFields
property. Gentics Mesh will utilize these fields in nodes in order to retrieve the node.urlFields
Try the example
https://demo.getmesh.io/api/v1/demo/webroot/cars/outatime
|
Description | API endpoint |
---|---|
Get the node with the given UUID. |
|
Try the example
https://demo.getmesh.io/api/v1/demo/nodes/fc3c85be82584ae2bc85be82588ae2b0?resolveLinks=short
|
{
"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
returns a navigation object for the provided node, while the /api/v1/:projectName/nodes/:nodeUuid/navigation
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./api/v1/:projectName/navroot/:path
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.
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 endpoint, with the URL parameter /api/v1/:projectName/navroot/:path
querying the project root node, i.e., :path
together with query parameter /
limiting the resulting nested JSON object to the top-level nodes.?maxDepth
Description | API endpoint |
---|---|
Returns a navigation object for the provided node. |
|
Return a navigation for the node which is located using the given path. |
|
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.
Try the example
https://demo.getmesh.io/api/v1/demo/nodes/72dbee3975054fce9bee397505cfcec5/navigation?resolveLinks=short&maxDepth=1
|
{
"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
}
}
} ]
}
Each node in Gentics Mesh provides information on where it is located within the node tree in terms of its
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.breadcrumb
The current node will not be included in the list, since all the information is already provided in other properties (i.e., , ) of node object itself.
|
In our demo app example, the
property for node Ford GT will therefore include the node Automobiles.breadcrumb
The
property will be returned in all API responses containing nodes. Using the breadcrumb
query parameter will also the paths of the nodes listed in the array.resolveLink
Description | API endpoint |
---|---|
Get all nodes of a project and return a paged list response. |
|
Get the node with the given UUID. |
|
Load the node or the node’s binary data, which is located using the provided path. |
|
Try the example
https://demo.getmesh.io/api/v1/demo/nodes/fc3c85be82584ae2bc85be82588ae2b0?resolveLinks=short
|
{
"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
}
}
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.
This functionality builds on top of the schema
and segmentField
property to define the path of a specific node.urlFields
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
for their child nodes.
The WebRoot API endpoint uses this information to resolve a given path to a node UUID. Each node in turn will provide a single containers
segment
to the full path via the referenced segmentField
.
In addition to that it is also possible to create completely custom URLs to your content using the
schema property. You can reference urlFields
string
and string list
fields within your schema using the property.
Those fields can in turn contain a custom path to your node. Gentics Mesh will only make sure that there are no collisions between custom paths of other nodes. Saving a node which uses the same urlField value would cause a conflict error.
It is important to note that conflicts between custom url field values and existing paths which are build using the segmentPath
property will not cause a conflict. You can use this in order to override an existing path to a node using a custom path.
Custom paths via the urlFields
property will always be resolved first and thus overrule the segmentField
paths.
Possible applications for the urlFields
property are:
Short URL support
Nice URL handling
Redirection handling
Using the WebRoot API it is possible to easily integrate Gentics Mesh with many known routing frameworks.
Framework | Language | Example |
---|---|---|
PHP |
||
JS |
||
Java,JS,Ceylon |
||
Ruby |
- |
Description | API endpoint |
---|---|
Load the node or the node’s binary data, which is located using the provided path. |
A WebRoot path may consist of multiple path segments, each corresponding to a node within the content tree. The
property from the schema is used to determine the node’s relevant field value.segmentField
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. |
Try the example
https://demo.getmesh.io/api/v1/demo/nodes/fc3c85be82584ae2bc85be82588ae2b0?resolveLinks=short
|
Loading the node with the given UUID using API endpoint
.GET /api/v1/:projectName/nodes/:nodeUuid
The WebRoot API, furthermore, directly supports delivering binary content (e.g., images, documents, etc.) using the
meta-data field of the fileName
field.binary
The header can be used to differentiate between binary and node responses. The values of this header can be either or . This allows to differentiate between binary content with and typical node responses also delivered with .
|
Try the example
https://demo.getmesh.io/api/v1/demo/nodes/df8beb3922c94ea28beb3922c94ea2f6/binary/image
|
Downloading a node’s binary field with the given name using API endpoint
.GET /api/v1/:projectName/nodes/:nodeUuid/binary/:fieldName
Try the example
https://demo.getmesh.io/api/v1/demo/webroot/images/ford-gt.jpg
|
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. |
In case, the binary data is an image, the WebRoot API allows to directly perform image manipulation such as cropping and resizing.
Try the example
https://demo.getmesh.io/api/v1/demo/webroot/images/ford-gt.jpg?rect=10,100,800,400&w=300&crop=rect
|
Find out more about this topic in our blogpost about Gentics Mesh’s Image Manipulation API and Interface.
Link resolving represents the counterpart of the WebRoot API - a node UUID can be resolved into a WebRoot path.
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,
will be transformed into {{mesh.link("2f2de9297c8143e8ade9297c8193e8fc", "en")}}
when using the /api/v1/demo/webroot/images/ford-gt.jpg
query parameter.?resolveLinks=full
The
query parameter defines if and how links are resolved:?resolveLinks
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
query parameter can be applied to all API endpoints returning nodes.?resolveLinks
In some cases it may be desireable to be able to create links which point to nodes within different projects. In these situations the link should no longer be relative but instead contain the domain and protocol which is used by the project of the referenced node.
You can specifiy the hostname
and ssl
flag when creating a project. This will in turn store this information within the created release of the project. Gentics Mesh will make use of this information once you render a foreign node’s link using the short type.
The links will automatically start with https://
if the ssl flag of the release has been set to true. You can update the hostname/ssl flag at any time by updating the release of the project.
Foreign links can only be rendered using the ?resolveLinks=short type. Other resolver types do not support this mechanism. |
Foreign links currently don’t contain any release reference thus it is not possible to render links to a foreign node within a specific release. Instead the foreign link resolving mechanism will automatically use the latest release of the node’s project to render the links. |
Description | API endpoint |
---|---|
Get all nodes of a project and return a paged list response. |
|
Get the node with the given UUID. |
|
Load the node or the node’s binary data, which is located using the provided path. |
|
Get a navigation object for the provided node. |
|
Return a navigation for the node which is located using the given path. |
|
In addition to the above, Gentics Mesh offers the
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./api/v1/utilities/linkResolver
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
is used to specify how links shall be resolved.?resolveLinks
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)
Images can be resized and/or cropped by appending the image manipulation query parameters on the relevant API endpoints.
The following image formats are supported: png
, jpg
, bmp
and gif
Endpoint: /api/v1/:projectName/nodes/:uuid/binary/:fieldname?w=220
It is also possible to use the image manipulation in combination with the WebRoot endpoint.
Endpoint: /api/v1/:projectName/webroot/:path?rect=10,100,800,400&crop=rect
Try the example
https://demo.getmesh.io/api/v1/demo/webroot/images/ford-gt.jpg?rect=10,100,800,400&crop=rect
|
It is mandatory to specify all four crop parameters when cropping an image. |
Responsive designs often suggest the usage of srcset images for responsive images. Sometimes those designs require image sizes which lead to cropped images. This could result in images which seem chopped off at the worst possible place or images which miss the important part.
You can however use the focal point feature in order to influence how the image should be cropped. Gentics Mesh will use the focal point information when cropping the image so that the focused area will remain in the image.
First you need to specify a focal point along with your image.
You can store the focal point information within the binary field of your image or use the fpx
and the fpy
query parameters when loading the image.
You can also use these parameters to override the stored focal point.
The width and height information via w
and h
parameter are also needed when loading the image.
Otherwise Gentics Mesh can’t tell which area of the image needs to be cropped.
Finally the fpdebug
parameter can be used to visualize the focal point. This is useful when testing designs and resize parameters.
Try the example
https://demo.getmesh.io/api/v1/demo/webroot/images/ford-gt.jpg?fpx=0.5&fpy=0.4&w=800&h=600&crop=fp&fpdebug=true
|
In some cases you may want to show just a single area of the image. In this case you can use the fpz
zoom parameter to zoom to the focal point area.
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. This will effectivly override the currently stored image with the image of the resulting operation.
Endpoint: POST /api/v1/:projectName/nodes/:uuid/binaryTransform/:fieldname
Example Request:
POST /api/v1/demo/nodes/df8beb3922c94ea28beb3922c94ea2f6/binaryTransform/image
...
{
"version" : "1.0",
"language" : "en",
"width" : 300
}
Name | Type | Mandatory | Description |
---|---|---|---|
crop |
string |
false |
Set the crop mode. Possible modes: rect : The rect mode will work in combination with the rect parameter and crop the specified area. fp : The fp mode will utilize the specified or pre-selected focal point and crop the image according to the position of the focus point and the specified image size. |
fpx |
number |
false |
Set the focal point x factor between 0 and 1 where 0.5 is the middle of the image. You can use this parameter in combination with the crop=fp parameter in order to crop and resize the image in relation to the given point. |
fpy |
number |
false |
Set the focal point y factor between 0 and 1 where 0.5 is the middle of the image. You can use this parameter in combination with the crop=fp parameter in order to crop and resize the image in relation to the given point. |
fpz |
number |
false |
Set the focal point zoom factor. The value must be greater than one. |
h |
number |
false |
Set image target height. The width will automatically be calculated if the height was omitted. |
rect |
string |
false |
Set image crop area. |
w |
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.
Binary data can be attached to node binary fields. The
endpoint can be used to POST binary data and thus update the stored binary field./api/v1/nodes/:uuid/binary/:fieldName
This endpoint is accepting , 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--
Gentics Mesh stores all binary files on the filesystem. The default directory
can be changed in the upload section of the main configuration file data/binaryfiles
.mesh.yml
The upload limit can be configured in bytes using the
setting.uploadOptions.byteLimit
For more information on available settings have a look at the administration guide.
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
query parameter. The ?lang
json property within an update or create request will be used to identify which language variant should be created or updated.language
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).
Gentics Mesh allows to configure a
in the main configuration file defaultLanguage
. This default language is used as a fallback in case:mesh.yml
the
query parameter has been omitted, orlang
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 .
|
Permissions allow to equip different groups of users with access to the content of your project.
In Gentics Mesh, we distinguish the concepts of user, group, and role for managing different needs of access.
A user represents a physical person or a client app that needs to interact with your content.
Groups are used to gather users of same content needs and access levels, e.g. administrators, editors, and users of your app.
A role describes a set of permissions on other elements in Gentics Mesh, e.g. nodes, tags, schemas, users.
By assigning a role to a group, the role’s permissions are efficiently granted to a set of users.
For reasons of readability, we will describe granting permissions to users though technically, permissions are granted to a specific role and applied to users via groups. |
Permission | Description |
---|---|
create |
grants the right to create instances of the element |
read |
grants read access to the element |
update |
grants the right to update the element |
delete |
grants the right to delete the element |
publish |
grants the right to publish/unpublish a node |
readPublished |
grants the right to read the published version of the node |
The and permissions are specifically available for node elements.
|
Most API responses within Gentics Mesh contain a list of permissions. This list indicates which permissions the requesting user has been granted on the returned element(s).
Try the example
Permission of user on node
https://demo.getmesh.io/api/v1/demo/nodes/fc3c85be82584ae2bc85be82588ae2b0?version=published
|
// permissions for node https://demo.getmesh.io/api/v1/demo/nodes/fd58237c79d64bf198237c79d6bbf107?version=published
...
"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 requesting user
has the anonymous
permission on the requested node, only. This means the user is allowed to read the published version of the node but not previous versions or a draft version of the requested element.readPublish
Furthermore the user is not allowed to
child nodescreate
a draft version of the noderead
the requested nodeupdate
the requested nodedelete
a draft version of the requested node, or publish
a node.unpublish
Gentics Mesh by default returns the version of nodes. This means for supporting the user and public content, you need to add the query parameter on all requests for nodes to avoid "Missing permissions on object" errors. Find out more in the Versioning section.
|
Following, we will discuss how to query, assign and revoke permissions in Gentics Mesh including the available API endpoints:
Description | API endpoint |
---|---|
Read the user permissions on element(s) that can be located by the specified path. |
|
Load the permissions between given role and the targeted element(s). |
|
Set the permissions between role and the targeted element(s). |
The examples provided subsequently, rely on our demo project.
There are dedicated API endpoints for querying permissions on elements.
The following example links, require prior authentication with user (credentials: admin/admin). Please refer to the authentication section to learn about the different authentication mechanisms provided by Gentics Mesh. The Insomnia REST client can be used to build and invoke requests from your browser to Gentics Mesh.
|
The
endpoint can be used to query a role’s permission on a specific element or set of elements.GET /api/v1/roles/:roleUuid/permissions/:path
For example, the authenticated
user is able to find out the configured permissions for role admin
on node Public User
.fc3c85be82584ae2bc85be82588ae2b0
Try the example with user
https://demo.getmesh.io/api/v1/roles/10447951fd264e6a847951fd266e6ae6/permissions/projects/217f8c981ada4642bf8c981adaa642c3/nodes/88fac3fbc61041c1bac3fbc610d1c182
Note, that a request with user
will yield a Missing object permissions error response.
|
GET https://demo.getmesh.io/api/v1/roles/10447951fd264e6a847951fd266e6ae6/permissions/projects/217f8c981ada4642bf8c981adaa642c3/nodes/88fac3fbc61041c1bac3fbc610d1c182
RESPONSE
{
"create": false,
"read": false,
"update": false,
"delete": false,
"publish": false,
"readPublished": true
}
Alternatively, you can use query the element using the respective API endpoint (e.g.
) and use the GET /api/v1/projectName/nodes
query parameter to find out another role’s (i.e. role
) permissions on the element:anonymous
Try the example with user
https://demo.getmesh.io/api/v1/demo/nodes/88fac3fbc61041c1bac3fbc610d1c182?role=10447951fd264e6a847951fd266e6ae6
|
GET https://demo.getmesh.io/api/v1/roles/10447951fd264e6a847951fd266e6ae6/permissions/projects/217f8c981ada4642bf8c981adaa642c3/nodes/88fac3fbc61041c1bac3fbc610d1c182
RESPONSE
...
"permissions" : { // permissions of requesting user admin
"create" : true,
"read" : true,
"update" : true,
"delete" : true,
"publish" : true,
"readPublished" : true
},
"rolePerms" : { // permissions of requested role anonymous
"create" : false,
"read" : false,
"update" : false,
"delete" : false,
"publish" : false,
"readPublished" : true
}
...
The endpoint
provides a shortcut for querying permissions for specific users directly, e.g., for user GET /api/v1/users/:userUuid/permissions/:path
, which is essentially inheriting all permissions from role anonymous
.anonymous
The
API endpoint can be used to assign or revoke permissions to/from a role.POST /api/v1/roles/:roleUuid/permissions/:path
It is important to note that permissions can be granted on individual elements and onto a set of elements, which is identified by the element path name (e.g.:
and /users/:uuid
)./users
Furthermore, the endpoint offers the property
for applying permissions recursively on child elements.recursive
Following, we go through all Gentics Mesh objects that can be subject to permissions.
In order to grant permission on individual or all users, one need to specify the path to be either
or /users/:uuid
, respectively./users
Applying permissions on
recursively will affect all users./users
If you need to grant permission on users of a specific group, please use the element path together with property .
|
The following example shows how to grant the
role the permission to read all users. Since this is an operation to be performed on a set of users, the element path Editor Role
needs to be used together with property /users
.recursive=true
Links used in the example 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 Insomnia REST client can be used to build and invoke requests from your browser to Gentics Mesh. |
POST https://demo.getmesh.io/api/v1/roles/6754d83b086244d894d83b086204d87f/permissions/users
BODY
{
"permissions": {
"create": false,
"read": true,
"update": false,
"delete": false,
"publish": false,
"readPublished": false
},
"recursive": true
}
RESPONSE
{
"message": "Permission for role Editor Role updated."
}
You can query the updated permissions with user
:admin
All possible role permissions on users are summarized in the following table.
Role permission | Element path | Permission | Recursive |
---|---|---|---|
Can create new users |
|
Create |
false |
Can read all users |
|
Read |
true |
Can update all users |
|
Update |
true |
Can delete all users |
|
Delete |
true |
Can read user |
|
Read |
false |
Can update user |
|
Update |
false |
Can delete user |
|
Delete |
false |
Permissions on a single or multiple groups are applied via
path and /groups/:uuid
path respectively./groups
Granting permissions on
recursively will affect all groups./groups
Granting permissions on
recursively will affect users of the group./groups/:uuid
The following example shows how to grant the
role the permission to read a specific group (i.e. Editor Role
) and its users (i.e. Client Group
). This operation needs to be applied recursively (i.e., webclient
), otherwise recursive=true
permissions would be granted to the group, only.read
Links used in the example 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 Insomnia REST client can be used to build and invoke requests from your browser to Gentics Mesh. |
POST https://demo.getmesh.io/api/v1/roles/6754d83b086244d894d83b086204d87f/permissions/groups/df81c23d9ff1450081c23d9ff195005e
BODY
{
"permissions": {
"create": false,
"read": true,
"update": false,
"delete": false,
"publish": false,
"readPublished": false
},
"recursive": true
}
RESPONSE
{
"message": "Permission for role Editor Role updated."
}
You can query the updated permissions with user
:admin
https://demo.getmesh.io/api/v1/roles/6754d83b086244d894d83b086204d87f/permissions/users
or alternatively with https://demo.getmesh.io/api/v1/groups/df81c23d9ff1450081c23d9ff195005e?role=6754d83b086244d894d83b086204d87f https://demo.getmesh.io/api/v1/groups/df81c23d9ff1450081c23d9ff195005e/users?role=6754d83b086244d894d83b086204d87f
All possible role permissions on groups are summarized in the following table.
Role permission | Element path | Permission | Recursive |
---|---|---|---|
Can create new groups |
|
Create |
false |
Can read all groups |
|
Read |
true |
Can update all groups |
|
Update |
true |
Can delete all groups |
|
Delete |
true |
Can read group |
|
Read |
false |
Can update group |
|
Update |
false |
Can delete group |
|
Delete |
false |
Can read group and its users |
|
Read |
true |
Can update group and its users |
|
Update |
true |
Can delete group and its users |
|
Delete |
true |
By granting permissions on roles, you effectively grant users the right to change permissions of other users.
Permissions on a single or multiple roles are applied via
path and /roles/:uuid
path respectively./roles
Granting permissions on
recursively will affect all roles./roles
The following example shows how to grant the
role permissions to create new roles and subsequently manage them (i.e., Editor Role
, read
, update
) but no access to existing roles.delete
Links used in the example 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 Insomnia REST client can be used to build and invoke requests from your browser to Gentics Mesh. |
POST https://demo.getmesh.io/api/v1/roles/6754d83b086244d894d83b086204d87f/permissions/roles
BODY
{
"permissions": {
"create": true,
"read": false,
"update": false,
"delete": false,
"publish": false,
"readPublished": false
},
"recursive": false
}
RESPONSE
{
"message": "Permission for role Editor Role updated."
}
You can query the updated permissions with user
:admin
All possible role permissions on roles are summarized in the following table.
Role permission | Element path | Permission | Recursive |
---|---|---|---|
Can create new roles |
|
Create |
false |
Can read all roles |
|
Read |
true |
Can update all roles |
|
Update |
true |
Can delete all roles |
|
Delete |
true |
Can read role |
|
Read |
false |
Can update role |
|
Update |
false |
Can delete role |
|
Delete |
false |
Permissions on a single or multiple schemas are applied via
path and /schemas/:uuid
path respectively./schemas
Granting permissions on
recursively will affect all schemas./schemas
Read permissions on a schema are needed for creating nodes based on that schema.
Role permission | Element path | Permission | Recursive |
---|---|---|---|
Can create new schemas |
|
Create |
false |
Can read all schemas, and create nodes |
|
Read |
true |
Can update all schemas |
|
Update |
true |
Can delete all schemas |
|
Delete |
true |
Can read schema, and create nodes |
|
Read |
false |
Can update schema |
|
Update |
false |
Can delete schema |
|
Delete |
false |
Permissions on a single or multiple microschemas are applied via
path and /microschemas/:uuid
path respectively./microschemas
Granting permissions on
recursively will affect all microschemas./microschemas
Read permissions on a microschema are needed for creating, reading, updating, and deleting micronodes based on that schema.
Role permission | Element path | Permission | Recursive |
---|---|---|---|
Can create new microschemas |
|
Create |
false |
Can read all microschemas, and create micronodes |
|
Read |
true |
Can update all microschemas |
|
Update |
true |
Can delete all microschemas |
|
Delete |
true |
Can read microschemas, and create micronodes |
|
Read |
false |
Can update microschemas |
|
Update |
false |
Can delete microschemas |
|
Delete |
false |
Permissions on a single or multiple projects are applied via
path and /projects/:uuid
path respectively./projects
Granting permissions on
will also affect sub elements, i.e., used schemas, microschemas, tagfamilies & tags, nodes & sub nodes of the project./projects/:uuid
Granting permissions on
recursively will affect all projects and their sub elements./projects
Role permission | Element path | Permission | Recursive |
---|---|---|---|
Can create new project |
|
Create |
false |
Can read all projects and sub elements |
|
Read |
true |
Can update all projects and sub elements |
|
Update |
true |
Can delete all projects and sub elements |
|
Delete |
true |
Can read published nodes and subnodes of all project |
|
Read Published |
true |
Can un/publish nodes and subnodes of all project |
|
Publish |
true |
Can read project and sub elements |
|
Read |
true |
Can update project and sub elements |
|
Update |
true |
Can delete project and sub elements |
|
Delete |
true |
Can read published nodes and subnodes of project |
|
Read Published |
true |
Can un/publish nodes and subnodes of project |
|
Publish |
true |
In order to grant permission on tag families the
path can be used./:projectName/tagFamilies
Granting permissions on
together with property /:projectName/tagFamilies/:uuid
allows setting permissions for tags of a tag family.recursive=true
Granting permissions on
together with property /:projectName/tagFamilies
allows setting permissions for all tag families and their tags.recursive=true
Role permission | Element path | Permission | Recursive |
---|---|---|---|
Can create new tag families |
|
Create |
false |
Can create new tag families and tags for tagFamilies |
|
Create |
true |
Can read all tag families and tags |
|
Read |
true |
Can update all tag families and tags |
|
Update |
true |
Can delete all tag families and tags |
|
Delete |
true |
Can create tags in tag family |
|
Create |
false |
Can read tag family |
|
Read |
false |
Can update tag family |
|
Update |
false |
Can delete tag family |
|
Delete |
false |
Can read tag family and tags |
|
Read |
true |
Can update tag family and tags |
|
Update |
true |
Can delete tag family and tags |
|
Delete |
true |
In order to grant permission on tags the
and /:projectName/tagFamilies/:uuid/tags
paths can be used./:projectName/tagFamilies/:uuid/tags/:uuid
Currently, using path
works same as using path /:projectName/tagFamilies/:uuid/tags
/:projectName/tagFamilies/:uuid
Granting permissions on
together with property /:projectName/tagFamilies/:uuid/tags
allows setting permissions for tags of a tag family, otherwise the property has no effect.recursive=true
Role permission | Element path | Permission | Recursive |
---|---|---|---|
Can create tags in tag family |
|
Create |
false |
Can read tag family |
|
Read |
false |
Can update tag family |
|
Update |
false |
Can delete tag family |
|
Delete |
false |
Can read tag family and tags |
|
Read |
true |
Can update tag family and tags |
|
Update |
true |
Can delete tag family and tags |
|
Delete |
true |
Can read tag |
|
Read |
false |
Can update tag |
|
Update |
false |
Can delete tag |
|
Delete |
false |
Permissions on a single or multiple nodes are applied via
and /:projectName/nodes
path:/:projectName/nodes/:uuid
is used to grant permissions on single nodes./:projectName/nodes/:uuid
together with property /:projectName/nodes
can be used to quickly grant permissions on all node of the project.recursive=true
In order to grant permissions on sub trees of the content tree
together with property /:projectName/nodes/:uuid
is to be used.recursive=true
Role permission | Element path | Permission | Recursive |
---|---|---|---|
Can create new sub nodes in all nodes of the project |
|
Create |
true |
Can read all project nodes (and all node versions) |
|
Read |
true |
Can update all nodes of the project |
|
Update |
true |
Can delete all nodes of the project |
|
Delete |
true |
Can read the published version of all project nodes |
|
ReadPublished |
true |
Can publish/unpublish all nodes of the project |
|
Publish |
true |
Can create new sub nodes in specified node |
|
Create |
false |
Can read specified node |
|
Read |
false |
Can update specified node |
|
Update |
false |
Can delete specified node |
|
Delete |
false |
Can read the published version specified node |
|
ReadPublished |
false |
Can publish/unpublish specified node |
|
Publish |
false |
Can create new sub nodes in specified node & sub nodes |
|
Create |
true |
Can read specified node & sub nodes |
|
Read |
true |
Can update specified node & sub nodes |
|
Update |
true |
Can delete specified node & sub nodes |
|
Delete |
true |
Can read the published version specified node & sub nodes |
|
ReadPublished |
true |
Can publish/unpublish specified node & sub nodes |
|
Publish |
true |
Permissions on a single or multiple releases are applied via
path and /releases/:uuid
path respectively./releases
Releases can not be deleted. Hence, permissions for deleting do not apply. |
Role permission | Element path | Permission | Recursive |
---|---|---|---|
Can create new release |
|
Create |
false |
Can read all releases |
|
Read |
true |
Can update all releases |
|
Update |
true |
Can read the release |
|
Read |
false |
Can update the release |
|
Update |
false |
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. |
Once a node has been created the initial version 0.1 will be assigned to its language variant.
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
version. Only a single draft version per language variant exists.draft
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
request on the POST
endpoint, which will publish all language variants of the node.
It is also possible to just publish specific language variants with dedicated /api/v1/:projectName/nodes/:uuid/published
requests on POST
./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
reference will also be updated to point to the major version, e.g. 1.0.draft
Furthermore, it is possible to retrieve information about the published status via a
request on GET
./api/v1/:/nodes/:uuid/published
Publishing node language variants requires the user to be assigned to a group with a role which provides the permission.
|
{
"availableLanguages" : {
"de" : {
"published" : false,
"version" : "0.4"
},
"en" : {
"published" : true,
"version" : "3.0",
"publisher" : {
"firstName" : "Joe",
"lastName" : "Doe",
"uuid" : "525f8d1a7ae8427e9f8d1a7ae8b27ef6"
},
"publishDate" : "2018-04-25T15:57:54.835Z"
},
"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. |
Similarly to publishing, the language variants of a node can be taken offline via a
request on DELETE
.
E.g., taking a specific node language variant with version 1.0 offline using /api/v1/:projectName/nodes/:uuid/published
will just change the node’s publish state. Version 1.0 will still be available.DELETE /api/v1/:projectName/nodes/:uuid/languages/:languageTag/published
Taking node language variants offline requires the user have permissions on the node.
|
It is possible to fetch older versions by specifying the
query parameter. Similarly, the published version of a node language variant can also be loaded using the parameter ?version
or the draft version via ?version=published
.?version=draft
Gentics Mesh by default returns the version of nodes. This means for supporting the user and public content, you need to add the 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 permission.
|
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
query parameter. If omitted the latest release will be used to execute the operation.?release=name
Implementations which use mesh should always reference a specific release. Otherwise the document structure could change without the implementation being aware of these changes. |
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
endpoint to query the migration status.
The /api/v1/admin/status/migrations
JSON property within the release response also indicates whether the node migration has been completed.migrated
Note: Migrated nodes will still have the same uuid as before.
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
request to PUT
will automatically trigger a schema migration of the affected nodes language variants within the release./api/v1/:projectName/releases/:uuid/schemas
{
"schemas" : [ {
"name" : "content",
"uuid" : "e989dc548f3048e989dc548f3048e95d",
"version" : "1.0"
}, {
"name" : "folder",
"uuid" : "6a9bf9f040bf47639bf9f040bf97633b",
"version" : "1.0"
}, {
"name" : "binary-data",
"uuid" : "8c61c8a96b0a430da1c8a96b0aa30dcf",
"version" : "1.0"
} ]
}
It is also possible to assign microschemas via a
request to PUT
to the release./api/v1/:projectName/releases/:uuid/microschemas
{
"microschemas" : [ {
"name" : "vcard",
"uuid" : "8bc0097a0dcf40ff80097a0dcf30ffaa",
"version" : "2.0"
}, {
"name" : "geolocation",
"uuid" : "0f1335abc9db40b89335abc9dbc0b89b",
"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. |
At the moment it is not possible to delete a release.
Releases enable Gentics Mesh to setup multiple content project tree structures.
Moving nodes can be scoped to a specific release using the
request parameter.
The project’s initial release will be used to execute the move operation if no release has been selected.?release
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 is also release specific. Deleting a node via
to DELETE
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./api/v1/:projectName/node/:uuid?release=winter2016
It is also possible to just delete a specific language variant via
to DELETE
from release winter2016./api/v1/:projectName/node/:uuid/languages/en?release=winter2016
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 are not release specific. |
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.
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
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./api/v1/users/:userUuid/reset_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
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./api/v1/users/:userUuid?token=TOKENCODE
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:
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"
}
}
Properties | Description |
---|---|
field |
Name of the field to be removed |
{
"operation" : "REMOVEFIELD",
"properties" : {
"field" : "fieldToBeRemoved"
}
}
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"
}
}
Properties | Description |
---|---|
field |
Field to be updated |
label |
New field label |
{
"operation" : "UPDATEFIELD",
"properties" : {
"field" : "fieldToBeUpdated",
"name" : "newName"
}
}
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"
}
}
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
and /api/v1/schemas/:uuid/diff
endpoints can be used to generate a list of changes by comparing the stored and posted schema./api/v1/microschemas/:uuid/diff
This list of changes can be modified and posted to
for schemas or /api/v1/schemas/: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./api/v1/microschemas/:uuid/changes
The SockJS compliant
endpoint can be used to register to migration specific messages./api/v1/eventbus
Additionally to websocket it is possible to query whether a migration is running via the
endpoint./api/v1/admin/status/migrations
Sending a schema to
using the /api/v1/schemas:uuid
method will conveniently combine the diff generation and invocation of the schema migration.PUT
Please note that by default conflicting data will be removed and this action can only be avoided by specifying a custom migration script.
Sometimes it is desired to overwrite the default migration behaviour.
The following migration script converts the number value from field
into a ISO-8601 date string which is then stored within the node.fields[fieldname]
field.node.fields[fieldname]
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" : { }
} ]
}
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.
The
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./api/v1/eventbus
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 |
mesh.cluster.node.joined |
Triggered when a node joined the cluster |
mesh.cluster.node.left |
Triggered when a node left the cluster |
mesh.cluster.db.status |
Triggered when the database status changes. The database can either be |
mesh.user.created |
Triggered on user creation |
mesh.user.updated |
Triggered on user update |
mesh.user.deleted |
Triggered on user deletion |
mesh.group.created |
Triggered on group creation |
mesh.group.updated |
Triggered on group update |
mesh.group.deleted |
Triggered on group deletion |
mesh.role.created |
Triggered on role creation |
mesh.role.updated |
Triggered on role update |
mesh.role.deleted |
Triggered on role deletion |
mesh.tag.created |
Triggered on tag creation |
mesh.tag.updated |
Triggered on tag update |
mesh.tag.deleted |
Triggered on tag deletion |
mesh.tagfamily.created |
Triggered on tagFamily creation |
mesh.tagfamily.updated |
Triggered on tagFamily update |
mesh.tagfamily.deleted |
Triggered on tagFamily deletion |
mesh.project.created |
Triggered on project creation |
mesh.project.updated |
Triggered on project update |
mesh.project.deleted |
Triggered on project deletion |
mesh.node.created |
Triggered on node creation |
mesh.node.updated |
Triggered on node update |
mesh.node.deleted |
Triggered on node deletion |
mesh.schema.created |
Triggered on schema creation |
mesh.schema.updated |
Triggered on schema update |
mesh.schema.deleted |
Triggered on schema deletion |
mesh.microschema.created |
Triggered on microschema creation |
mesh.microschema.updated |
Triggered on microschema update |
mesh.microschema.deleted |
Triggered on microschema deletion |
mesh.release.created |
Triggered on release creation |
mesh.release.updated |
Triggered on release update |
mesh.release.deleted |
Triggered on release deletion |
Clustering is described in detail in our dedicated clustering documentation.