This documentation provides information on the structure and functionality of the Gentics Mesh server and its API endpoints.

TL;DR

Gentics Mesh is a API-Centric CMS Server written in Java which enables you to store and retrieve JSON documents and binaries via REST. Gentics Mesh will also provide you a lot of powerful tools build around and for those documents.

  • Document level permission system

  • Search API

  • Webroot API for easy integration with modern routing frameworks

  • Image Manipulation API

  • Tagging system

  • Schema system for documents

  • Clustering (in development)

  • Versioning of your documents

GraphQL

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

Examples

{ me { username, uuid } }

Field query:

{ node(path: "/Yachts/Pelorus") { container(language: "en") { fields { ... on vehicle { name description } } } } }

GraphiQL Browser

Once authenticated you can access the interactive GraphiQL browser. /api/v1/:projectName/graphql/browser/ .

Try our Demo.

Limitations

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

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

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

REST API

The Gentics Mesh REST API provides endpoints which enable you to invoke CRUD operations on any Gentics Mesh element. There are many things you can do with the REST API. For example:

  • You can create new users.

  • You can create nodes and tag them with tags.

  • Binary data can be added to nodes.

  • You can find nodes which match your search parameters.

All REST API responses are only available in JSON.

The Postman chrome extension can be used to build and invoke requests from your browser to Gentics Mesh.

Authentication

Overview

Gentics Mesh currently supports multiple ways of authentication. You can login via:

  • sending Basic Authentication header

  • sending JSON Data

  • sending a JWT token

Each way will store a JWT in the cookie which is used to authenticate the user for succeeding requests.

The token only lasts a certain amount of time (which can be configured in the mesh.yml file), so it might be necessary to refresh the token. The JWT will be automatically renewed by every request on the Gentics Mesh API. Additionally it is also possible to manually refresh the token using a GET request on the /api/v1/auth/refresh endpoint. This will set create new token which has a refreshed expire time.

JWT Configuration

The Json Web Token store can be configured within the main mesh.yml config file.

You also have to set the keystore secret and the path to the keystore file. See above for an example.

Before using JWT you have to create a keystore which holds the secret to generate the signature for the token. Currently only the HS256 algorithm is supported. You can use the java keytool to create a new keystore.

Here is an example on how to create a keystore:

keytool -genseckey -keystore keystore.jceks -storetype jceks -storepass secret -keyalg HMacSHA256 -keysize 2048 -alias HS256 -keypass secret

After creating the keystore, set the file path of the keystore and the password to access the keystore in the mesh.yml configuration file.

Example:

security:
  tokenExpirationTime: 3600
  signatureSecret: "secret"
  keystorePath: "keystore.jceks"
Basic Auth

A user can be authenticated by invoking a regular GET request to /api/v1/auth/login which includes a [Basic Authentication HTTP header.

Json Web Token (JWT)

The JWT token can be provided in two ways. By default it is passed along with a cookie value. This is useful for embedding binary image nodes directly in HTML.

Alternativly the token can be passed along within the Authorization header which includes the regular JWT "Bearer <Token>", where <Token> is the token you received from the login/cookie.

JSON

Alternatively the user can POST his credentials to /api/v1/auth/login in order to retrieve a token.

The JSON object must containing these fields:

  • username The username of the user

  • password The password of the user

If the authentication was successful, the server will respond with a JSON object containing a single field:

  • token The token to be sent on every subsequent request.

Additionally the token will also be provided via a cookie.

Encoding

Gentics Mesh expects and returns UTF-8 encoded data. Sending data in any other encoding format will result in encoding issues.

Headers

It is important to set the Content-Type: application/json when sending JSON data and to also set the Accept header in order to signal Gentics Mesh that your client is accepting JSON.

Content-Type: application/json
Accept: application/json

A request which is not well formatted may fail. Gentics Mesh will do its best to identify the issue and return a meaningful error response in those cases.

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.

File Upload

Binary data can be attached to node binary fields which have been created using a schema that lists one or more 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 only multipart/form-data . 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.

----------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--

Examples

Create a new node

It is mandatory to specify the parentNode reference, language and schema field when creating a node. It is possible specify the schema uuid instead of the name. At least one property within the schema object must be set.

POST /api/v1/demo/nodes HTTP/1.1
Host: localhost:8080
Cookie: mesh.session=61ac7969-e5ad-4c28-bc0f-0869a04e4db1
Content-Type: application/json
Accept: application/json

{
  "language" : "en",
  "fields" : {
    "name" : "DeLorean DMC-12",
    "description" : "The DeLorean DMC-12 is a sports car manufactured by John DeLorean's DeLorean Motor Company for the American market from 1981–83."
  },
  "parentNode" : {
    "uuid" : "dda22b23bc94474ca22b23bc94274cda"
  },
  "schema" : {
    "name" : "vehicle"
  }
}

Update an existing node

The created node can be updated via a PUT request. You may only include those field which should be updated.

PUT /api/v1/demo/nodes/5af8d0e077e34361b8d0e077e353619e HTTP/1.1
Host: localhost:8080
Cookie: mesh.session=61ac7969-e5ad-4c28-bc0f-0869a04e4db1
Content-Type: application/json
Accept: application/json

{
  "language" : "en",
  "fields" : {
    "filename" : "index-renamed.en.html",
    "relatedProduct-" : {
      "uuid" : "251dfe98e4d94f3e9dfe98e4d97f3e12"
    },
    "price" : 100.1,
    "enabled" : true,
    "release" : "2017-03-28T13:35:34.342Z",
    "categories" : [ {
      "uuid" : "5a619bf78fce4a14a19bf78fceda14c8"
    }, {
      "uuid" : "b4ee998490a1496eae998490a1796eab"
    }, {
      "uuid" : "d6d22d2cb3e84fdf922d2cb3e83fdfcc"
    } ],
    "names" : [ "Jack", "Joe", "Mary", "Tom" ],
    "categoryIds" : [ 1, 42, 133, 7 ],
    "location" : {
      "uuid" : "a0786078bda340e1b86078bda340e148",
      "microschema" : {
        "name" : "geolocation",
        "uuid" : "69926d8d9e554b35926d8d9e55bb35b5"
      },
      "fields" : {
        "latitude" : 48.208330230278,
        "longitude" : 16.373063840833
      }
    },
    "locations" : [ {
      "uuid" : "bcf0484ee83c4b39b0484ee83c7b39ef",
      "microschema" : {
        "name" : "geolocation",
        "uuid" : "199b331c3262428a9b331c3262028a32"
      },
      "fields" : {
        "latitude" : 48.208330230278,
        "longitude" : 16.373063840833
      }
    }, {
      "uuid" : "22c570086eca43128570086eca831284",
      "microschema" : {
        "name" : "geolocation",
        "uuid" : "c33ae4fca6c84b35bae4fca6c86b35bf"
      },
      "fields" : {
        "latitude" : 48.137222,
        "longitude" : 11.575556
      }
    } ]
  }
}

Add a tag to a node

Tagging nodes requires just a simple PUT request.

PUT /api/v1/demo/nodes/5af8d0e077e34361b8d0e077e353619e/tags/ba2edcdb1234489daedcdb1234289d38 HTTP/1.1
Host: localhost:8080
Cookie: mesh.session=61ac7969-e5ad-4c28-bc0f-0869a04e4db1
Accept: application/json

Building blocks

Gentics Mesh provides a various building blocks which can be used in order to setup your content structure. Below are elements which can be used to create your project datastructure.

overview

Users

Users can log into Gentics Mesh in order to interact with other elements.

Endpoint: /api/v1/users/:uuid

Property Description

uuid

Uuid of the user

lastname

Lastname of the user

firstname

Firstname of the user

username

Username of the user (mandatory)

emailAddress

Email Address of the user

nodeReference

Node reference which can be used to store additional user data.

enabled

Enabled flag. Disabled users can no longer log into Gentics Mesh. A deleted user will not be completely removed. Instead the user will just be disabled.

groups

List of group references of the user

creator

User reference of the creator

created

Epoch creation date

editor

User reference of the last editor

edited

Epoch last edited date

rolePerms

Role permissions on the element

permissions

User permissions on the element

Response Sample

{
  "uuid" : "f1ee72c509e147c4ae72c509e107c4ee",
  "creator" : {
    "firstName" : "Joe",
    "lastName" : "Doe",
    "uuid" : "5b1f2bbe668b4bef9f2bbe668b3bef6c"
  },
  "created" : "2017-03-28T13:35:33.624Z",
  "editor" : {
    "firstName" : "Joe",
    "lastName" : "Doe",
    "uuid" : "3f8838c418b84ed38838c418b8bed323"
  },
  "edited" : "2017-03-28T13:35:33.625Z",
  "lastname" : "Doe",
  "firstname" : "Joe",
  "username" : "jdoe",
  "emailAddress" : "j.doe@nowhere.com",
  "nodeReference" : {
    "projectName" : "dummy",
    "uuid" : "779bf784a03d41659bf784a03da165db"
  },
  "enabled" : true,
  "groups" : [ {
    "name" : "editors",
    "uuid" : "3fa6bbf00c844bb1a6bbf00c845bb148"
  } ],
  "permissions" : {
    "create" : true,
    "read" : true,
    "update" : true,
    "delete" : true,
    "publish" : false,
    "readPublished" : false
  }
}

Groups

Groups are used to organize users. Roles can be assigned to groups. A user in a group with roles inherits those roles and the permissions that are bound to those roles. Groups can’t be nested.

Endpoint: /api/v1/groups/:uuid

Property Description

uuid

Uuid of the group

name

Name of the group

roles

List of role references (name/uuid)

creator

User reference of the creator

created

Epoch creation date

editor

User reference of the last editor

edited

Epoch last edited date

rolePerms

Role permissions on the element

permissions

User permissions on the element

Response Sample

{
  "uuid" : "2d0f7b44c4714c3b8f7b44c471bc3b61",
  "creator" : {
    "firstName" : "Joe",
    "lastName" : "Doe",
    "uuid" : "76971a6b082f4779971a6b082fc779fa"
  },
  "created" : "2017-03-28T13:35:33.761Z",
  "editor" : {
    "firstName" : "Joe",
    "lastName" : "Doe",
    "uuid" : "f31ade04e13d49cc9ade04e13d59cc94"
  },
  "edited" : "2017-03-28T13:35:33.761Z",
  "name" : "New group name",
  "roles" : [ {
    "name" : "admin",
    "uuid" : "5e8479b2d2a24b528479b2d2a26b5204"
  } ],
  "permissions" : {
    "create" : true,
    "read" : true,
    "update" : true,
    "delete" : true,
    "publish" : false,
    "readPublished" : false
  }
}

Roles

Roles are used to assign permissions to objects. A role can be assigned to multiple groups. Users can only assign permissions to roles to which they have access. Roles can’t be nested.

Endpoint: /api/v1/roles/:uuid

Property Description

uuid

Uuid of the role

name

Name of the role

groups

List of group references of the role

creator

User reference of the creator

created

Epoch creation date

editor

User reference of the last editor

edited

Epoch last edited date

rolePerms

Role permissions on the element

permissions

User permissions on the element

Response Sample

{
  "uuid" : "7c3b97553e85426dbb97553e85d26db8",
  "creator" : {
    "firstName" : "Joe",
    "lastName" : "Doe",
    "uuid" : "7add0c748f0442019d0c748f042201c5"
  },
  "created" : "2017-03-28T13:35:33.703Z",
  "editor" : {
    "firstName" : "Joe",
    "lastName" : "Doe",
    "uuid" : "3cba3784076d4e4bba3784076dce4b22"
  },
  "edited" : "2017-03-28T13:35:33.703Z",
  "name" : "New role name",
  "groups" : [ ],
  "permissions" : {
    "create" : true,
    "read" : true,
    "update" : true,
    "delete" : true,
    "publish" : false,
    "readPublished" : false
  }
}

Projects

A project is the base element your content structure which includes tagfamilies and your node tree. Schemas can be assigned to projects in order to allow creation of nodes which use one of the assigned schemas.

Endpoint: /api/v1/projects/:uuid

Property Description

uuid

Uuid of the project

name

Name of the project

rootNodeUuid

Uuid of the project root node

creator

User reference of the creator

created

Epoch creation date

editor

User reference of the last editor

edited

Epoch last edited date

rolePerms

Role permissions on the element

permissions

User permissions on the element

Response Sample

{
  "uuid" : "3d3f48ec20dd47a6bf48ec20ddd7a61d",
  "creator" : {
    "firstName" : "Joe",
    "lastName" : "Doe",
    "uuid" : "5f5f5e8a4be24e379f5e8a4be22e370f"
  },
  "created" : "2017-03-28T13:35:33.795Z",
  "editor" : {
    "firstName" : "Joe",
    "lastName" : "Doe",
    "uuid" : "5955b97461aa418a95b97461aa418a15"
  },
  "edited" : "2017-03-28T13:35:33.795Z",
  "name" : "New project name",
  "rootNode" : {
    "uuid" : "32d73233e93e4ee9973233e93e4ee9ab"
  },
  "permissions" : {
    "create" : true,
    "read" : true,
    "update" : false,
    "delete" : true,
    "publish" : false,
    "readPublished" : false
  }
}

Tag Families

Tag families are base elements for tags which are bound to single project. Tag families can’t be nested.

Endpoint: /api/v1/:projectName/tagfamilies/:uuid

Property Description

uuid

Uuid of the tag family

name

Name of the tag family

creator

User reference of the creator

created

Epoch creation date

editor

User reference of the last editor

edited

Epoch last edited date

rolePerms

Role permissions on the element

permissions

User permissions on the element

Response Sample

{
  "creator" : {
    "firstName" : "Joe",
    "lastName" : "Doe",
    "uuid" : "1e4af33058ca4d588af33058cacd5841"
  },
  "created" : "2017-03-28T13:35:34.457Z",
  "editor" : {
    "firstName" : "Joe",
    "lastName" : "Doe",
    "uuid" : "a19a410881524aa79a410881521aa74f"
  },
  "edited" : "2017-03-28T13:35:34.457Z",
  "name" : "Nicer colors",
  "permissions" : {
    "create" : true,
    "read" : true,
    "update" : false,
    "delete" : true,
    "publish" : false,
    "readPublished" : false
  }
}

Tags

Tags can be added to nodes. Tags can not be hierarchically structured.

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

Property Description

uuid

Uuid of the tag

name

Name of the tag

tagFamily

Tag family reference of the tag

creator

User reference of the creator

created

Epoch creation date

editor

User reference of the last editor

edited

Epoch last edited date

rolePerms

Role permissions on the element

permissions

User permissions on the element

Response Sample

{
  "uuid" : "9c8fd5607870462c8fd5607870562cef",
  "creator" : {
    "firstName" : "Joe",
    "lastName" : "Doe",
    "uuid" : "414ce0a708504cb48ce0a708500cb4ef"
  },
  "created" : "2017-03-28T13:35:34.462Z",
  "editor" : {
    "firstName" : "Joe",
    "lastName" : "Doe",
    "uuid" : "9dd25afad5ab487b925afad5ab087b1b"
  },
  "edited" : "2017-03-28T13:35:34.462Z",
  "tagFamily" : {
    "name" : "colors",
    "uuid" : "9e051a53a396440d851a53a396140d83"
  },
  "name" : "Red",
  "permissions" : {
    "create" : true,
    "read" : true,
    "update" : true,
    "delete" : true,
    "publish" : false,
    "readPublished" : false
  }
}

Nodes

Nodes are the main structural building blocks for your content. You may create different schemas to create multiple types of nodes. Nodes can be hierarchically structured if the schema is allowing this. The type of a node is always defined by the assigned schema. Nodes can be tagged by any number of tags.

It is important to understand that a node is just a container for language variants. These language variants will store your fields. You can query individual language variants by appending the ?lang request parameter. The language json property within an update or create request will be used to identify which language variant should be created or updated.

Endpoint: /api/v1/:projectName/nodes/:uuid?lang=de,en&version=draft&release=winter2016

Property Description

uuid

Uuid of the node

fields

Node fields of the current language

parentNode

Node reference to the parent node. The project basenode has no parent node.

language

Language tag of the current language

availableLanguages

List of available languages

languagePaths

Map with languages and the corresponding webroot path. Note that the field will only be added when a resolveLinks parameter has been specified.

tags

List of tags that were used to tag the node

project

Project reference

schema

Schema reference of the node

isContainer

Flag that indicates that the node is a container and may contain children

childrenInfo

JSON structure which contains information on the amount and type of child elements

published

Published flag

displayField

Key of the field that will be used to retrieve the display name value. (eg. "title" for blogpost nodes and "filename" for binary nodes)

segmentField

Key of the field that will be used to build a path segment of this node. The path segments create the webroot path to the element.

creator

User reference of the creator

created

Epoch creation date

editor

User reference of the last editor

edited

Epoch last edited date

rolePerms

Role permissions on the element

permissions

User permissions on the element

Response Sample

{
  "uuid" : "923974f77c32414fb974f77c32714f8d",
  "creator" : {
    "firstName" : "Joe",
    "lastName" : "Doe",
    "uuid" : "3ebb128906724495bb12890672b495bc"
  },
  "created" : "2017-03-28T13:35:34.343Z",
  "editor" : {
    "firstName" : "Joe",
    "lastName" : "Doe",
    "uuid" : "2d009add943b4b06809add943bdb06fc"
  },
  "edited" : "2017-03-28T13:35:34.343Z",
  "parentNode" : {
    "uuid" : "d3f212f5e716424eb212f5e716b24e5b",
    "displayName" : "parentNodeDisplayName"
  },
  "tags" : [ {
    "name" : "red",
    "uuid" : "1f34c262642b406fb4c262642b706f9f",
    "tagFamily" : "colors"
  }, {
    "name" : "green",
    "uuid" : "a45339bfdd724f9f9339bfdd726f9ff2",
    "tagFamily" : "colors"
  }, {
    "name" : "car",
    "uuid" : "00ced7ad7de54c6c8ed7ad7de5ec6cf1",
    "tagFamily" : "vehicles"
  }, {
    "name" : "ship",
    "uuid" : "0f765bce945746a5b65bce9457d6a56d",
    "tagFamily" : "vehicles"
  } ],
  "childrenInfo" : { },
  "schema" : {
    "name" : "content",
    "uuid" : "a1ee3125fdad42e6ae3125fdad92e685",
    "version" : 1
  },
  "fields" : {
    "name" : "Name for language tag en",
    "filename" : "dummy-content.en.html",
    "teaser" : "Dummy teaser for en",
    "content" : "Content for language tag en"
  },
  "breadcrumb" : [ {
    "uuid" : "bc74e1336aeb4ab9b4e1336aeb5ab946",
    "displayName" : "news",
    "path" : "/news"
  }, {
    "uuid" : "9077c028163a47b8b7c028163a67b807",
    "displayName" : "2015",
    "path" : "/news/2015"
  } ],
  "container" : false,
  "permissions" : {
    "create" : true,
    "read" : true,
    "update" : false,
    "delete" : false,
    "publish" : false,
    "readPublished" : false
  }
}

Query Parameters

Name Description

lang

The lang query parameter can be used to retrieve a node in a particular language.

role

The role query parameter may be used in order to add permission information related to the specified role to the response. This may be useful when you are logged in as admin but you want to retrieve the editor role permissions on a given node. When used, the response will include the rolePerms property which lists the permissions for the specified role. Endpoint: /api/v1/:projectName/nodes?role=:roleUuid

release

The specific release to be used for loading the node.

version

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

Creation

It is mandatory to set the language and parentNodeUuid parameter within the JSON request when sending a create request via POST to the nodes endpoint.

Depending on the used schema it may also be mandatory to add fields to the request which are flagged as mandatory.

{
  "language" : "en",
  "fields" : {
    "name" : "DeLorean DMC-12",
    "description" : "The DeLorean DMC-12 is a sports car manufactured by John DeLorean's DeLorean Motor Company for the American market from 1981–83."
  },
  "parentNode" : {
    "uuid" : "dda22b23bc94474ca22b23bc94274cda"
  },
  "schema" : {
    "name" : "vehicle"
  }
}

Updating

It is mandatory to set the language and version parameter within the JSON request. Updating may fail if a segment path conflict was detected. The request could also fail if a unresolvable version conflict has been detected. See versioning for more information.

Schemas

A schema defines the type and name of each field for a node. You can think of a schema as a blueprint for new nodes.

Endpoint: /api/v1/schemas/:uuid

{
  "uuid" : "25856a88b0ce4a40856a88b0ceaa408d",
  "displayField" : "name",
  "segmentField" : "name",
  "container" : false,
  "version" : 0,
  "name" : "ExampleSchema",
  "fields" : [ {
    "name" : "name",
    "label" : "Name",
    "required" : false,
    "type" : "string"
  }, {
    "name" : "number",
    "label" : "Number",
    "required" : false,
    "type" : "number"
  }, {
    "name" : "html",
    "label" : "Teaser",
    "required" : false,
    "type" : "html"
  }, {
    "name" : "list",
    "label" : "List of nodes",
    "required" : false,
    "listType" : "node",
    "type" : "list",
    "allow" : [ "content", "video" ]
  }, {
    "name" : "node",
    "required" : false,
    "type" : "node",
    "allow" : [ "content", "video", "image" ]
  }, {
    "name" : "location",
    "label" : "Location",
    "required" : false,
    "type" : "micronode",
    "allow" : [ "geolocation" ]
  }, {
    "name" : "locationlist",
    "label" : "List of Locations",
    "required" : false,
    "listType" : "micronode",
    "type" : "list",
    "allow" : [ "geolocation" ]
  } ],
  "permissions" : {
    "create" : true,
    "read" : true,
    "update" : true,
    "delete" : true,
    "publish" : false,
    "readPublished" : false
  }
}

Configuration properties

The following configuration properties may be specified:

  • container Set to true to indicate that this schema can contain child nodes. This will cause the response object for such nodes to have a childrenInfo property.

  • displayField Used to specify which field (as defined in the "fields" list) should be considered the title for the purpose of displaying a list of nodes. The value must be a string which corresponds to the name of one of the schema’s fields, and additionally that field must not be of type "list", "node".

Schema Field

A field is defined by an object which must have the following properties:

  • name A unique name to identify the field

  • type The type of data to be stored in this field.

The following optional properties may be applied to any type of field:

  • required If true, this field may not be left empty.

  • label A human-readable label for the field to be used as a form label in the admin UI. If not defined, the "name" field would be used.

In addition to the above, certain types expose additional properties with which to configure the field. Such additional properties are defined in the [Types](#types) section.

Schema Field Types

Name Type Key Description

String

string

A string field type may have an allow property which acts as a white list for allowed field values

HTML

html

A html field type does not have any special configuration settings at this point of time.

Number

number

A number field type has three optional config properties: "min" is the lowest permitted value, "max" is the greatest permitted value, and "step" is the size of the permitted increment in value. For example:

Date

date

The date field type stores a date in a epoch date format.

Boolean

boolean

A boolean field type does not have any special config settings.

Binary

binary

The binary field type stores binary and binary related meta data (e.g: filename, sha512sum, image width and height, mimetype..). Binary fields within nodes can be updated using the fields API.

Node

node

A node field type must have an allow property which acts as a white list for schemas which may be used. If allow is an empty array, any type of node may be used.

Micronode

micronode

A micronode field type stores a single micronode. A micronode is similar to a node but it is directly bound to the node and thus is not accessible within the project node tree structure. Typical usecases for micronodes are galleries, location boxes, vcards.

List

list

A list field must be typed via the listType property. Possible listTypes are node boolean string html number date micronode

Media type whitelist for binary schemas

Binary schemas should be able to specify which media types (aka MIME type or Content-type) they may contain. This would be done by means of a whitelist which is an array of multiple regular expressions.

Since the JSON standard does not have a special regex type, it would need to be specified as a string, but would actually be converted to and interpreted as a regex by Gentics Mesh.

Software Stack

Component Type Version

OrientDB

Graph Database

2.2.x

Ferma

OGM

2.2.x

Elasticsearch

Search Engine

2.3.x

Vert.x

Core Framework

3.3.x

Hazelcast

In-Memory Data Grid

3.5.x

https://google.github.io/dagger/

Dependency Injection

2.6.x

Installation

There is no dedicated installation procedure for Gentics Mesh. You just download the mesh jar file and start it using Java.

Oracle Java Runtime 1.8.0_40 or newer is required to run Gentics Mesh.

java -jar mesh-demo-0.9.0.jar

Docker

Alternatively you can start mesh using docker via:

The mesh-demo image contains mesh which provides the demo data and demo application.

docker run -p 8080:8080 gentics/mesh-demo
or
docker run -v /opt/data/:/mesh/data -p 8080:8080 gentics/mesh-demo

The mesh image contains an empty Gentics Mesh server without any demo content.

docker run -p 8080:8080 gentics/mesh
or
docker run -v /opt/data/:/mesh/data -p 8080:8080 gentics/mesh

System Requirements

  • Oracle Java Runtime (JRE) 8u60+

System Configuration

The max open file limit on Linux has to be raised on most Linux systems since the embedded graph database and elasticsearch server often exceed the amount of concurrent open files.

Edit /etc/security/limits.conf and add these two lines:

Mesh   soft    nofile  60000
Mesh   hard    nofile  60000

Edit /etc/pam.d/su and uncomment or add the following line:

session    required   pam_limits.so

Please note that this change may require a logout and login after it is being applied.

Settings

The main mesh.yml configuration file contains various settings to configure the graph database and various file system paths.

---
clusterMode: false
defaultMaxDepth: 10
defaultLanguage: "en"
updateCheck: true
tempDirectory: "/opt/mesh/data/tmp"
httpServer:
  port: 8080
  corsAllowedOriginPattern: ""
  enableCors: false
storage:
  directory: "data/graphdb"
  backupDirectory: "data/backup"
  exportDirectory: "data/export"
  startServer: false
  parameters: {}
search:
  directory: "data/searchindex"
  httpEnabled: false
upload:
  byteLimit: 262144000
  directory: "data/binaryFiles"
  tempDirectory: "/opt/mesh/data/tmp/temp-uploads"
security:
  tokenExpirationTime: 3600
  signatureSecret: "secret"
  keystorePath: "keystore.jceks"
image:
  imageCacheDirectory: "data/binaryImageCache"
  maxWidth: 2048
  maxHeight: 2048
Configuration Type Description

clusterMode

Flag

The internal hazelcast in-memory data grid will be enabled if this flag is set to true.

updateCheck

Flag

A update check to the mesh update server will be invoked during startup if this flag is set to true.

defaultPageSize

Number

Default page size.

defaultLanguage

String

Default language which is used as a fallback when no language was specified.

verticles

List

List of vert.x java verticle classes which will be loaded during startup.

tempDirectory

Path

Path to the main temporary filesystem directory.

HTTPS/SSL

To enable https you have to specify the server key and the server certificate within the configuration.

You can create a snakeoil certificate for testing purposes this way:

openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 90 -nodes

Server Options

Configuration Type Description

httpServerOptions.port

Number

Http Port number.

httpServerOptions.ssl

Boolean

Enable or disable SSL support.

httpServerOptions.corsAllowedOriginPattern

RegEx

Regex which will validate the origin CORS header.

httpServerOptions.enableCors

Boolean

Enable CORS support.

httpServerOptions.certPath

Path

SSL certificate path.

httpServerOptions.keyPath

Path

SSL key path.

Storage Options

By default all specified directories are relative to the current working directory.

Configuration Type Description

storageOptions.directory

Path

Path to the graph database storage location.

storageOptions.backupDirectory

Path

Backup directory.

storageOptions.exportDirectory

Path

Export directory.

storageOptions.startServer

Boolean

Flag that indicates whether the graph database server component should be started. By default only an embedded graph database is used which does not start a graph server.

storageOptions.parameters

JSON

Additional JSON parameters that will be passed on to the used graph database implementation.

Upload Options

Configuration Type Description

uploadOptions.byteLimit

Number

Upload limit in bytes.

uploadOptions.directory

Path

Filesystem directory for uploaded binary data.

uploadOptions.tempDirectory

Path

Temporary directory for uploaded binary data. Finished files will be moved to the upload directory.

Cache Options

Gentics Mesh does not manage any cache structure but it is possible to tweak the underlying graph and elasticsearch database cache settings.

Features

Password Recovery

A user who lost his password can recover it using a recovery token. This token can be issued by a user or admin which has permissions to create new users. The /api/v1/users/:userUuid/token endpoint will return a token code which can for example be passed along to an email service which sends a recovery email to the user which includes this token.

The user can use this token to update his user record via /api/v1/users/:userUuid?token=TOKENCODE. This works even if the user is not authenticated. The token will be invalidated once it has been used.

Permissions

Permissions exist between roles and other elements (including other roles). Most responses within Gentics Mesh will contain a list of permissions which may indicate that CRUD operations on the returned element is restricted in a way.

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

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 the set of elements which is identified by the endpoint name (e.g: /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

WebRoot

The /api/v1/:projectName/webroot/:path endpoint can be used to access nodes via a regular web path instead of using uuids.

Example: /api/v1/demo/webroot/Vehicle%20Images/ford-gt.jpg?width=1000

This makes it possible to 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

-

A webroot path consists of multiple path segments. Each segment of the url must be URL encoded. A list of segments can be provided by a single node. The segmentField information from the schema is used to determine the segment field value which the node provides. Each language of the node must provide different path segment.

The Ford GT Image node for example provides the path segment ford-gt.jpg since the used schema vehicleImage points to the binary field image. The binary field contains the filename ford-gt.jpg.

The segmentField parameter within the schema is therefore used to map in between fields and the path segment.

  • ford-gt.jpg/api/v1/demo/webroot/Vehicle%20Images/ford-gt.jpg

The binary data will be returned if the path targets a node in which the binary fileName property provides the segment. It is possible to differentiate between a binary response and a normal JSON response by checking whether the Content-Disposition header parameter is set. The header value will only be set when binary data is returned.

The router implementation can use this in order to be able to to decide whether to handle the JSON data or whether the binary data should just be passed through to the requester.

Navigations

There are two ways of generating a nested navigation response. You can either use /api/v1/:projectName/nodes/:uuid/navigation or /api/v1/:projectName/navroot/:path endpoints.

Each endpoint will return a navigation response which contains the nested navigation tree structure. The maxDepth parameter may be used to limit the navigation depth (default: 10).

Gentics Mesh will try to resolve any found mesh-link within any text field of a node if the resolveLinks query parameter has been set to either short, medium or full.

Example: {{mesh.link("2f2de9297c8143e8ade9297c8193e8fc", "en")}} will be transformed into /api/v1/demo/webroot/Vehicle%20Images/ford-gt.jpg when using the ?resolveLinks=full

Valid Links:

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

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

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

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

Resolver

The /api/v1/utilities/linkResolver endpoint can be used to resolve mesh links within the posted text data. This is useful when resolving links for a preview page.

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" : { }
  } ]
}

Versioning

In order to grasp the concept of versioning in Gentics Mesh it is important to remember that Nodes are containers for language variants. 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 and even Nodes are not versioned.

Various interactions have different effects for versioning in Mesh. Below is a list of actions which involve versioning.

Node Creation

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

Node Updates

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

  • No Locks and Conflict detection

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. 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 automatically compared in order to determine whether the current update request causes a conflict with a newer edit request. 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 a update request is called the draft version. Only a single draft version per language exists.

Publishing Nodes

Node language variant can be published and taken offline. This is especially useful if you want to first work on a draft and review it and later publish it. Publishing a just requires a PUT request on /api/v1/:projectName/nodes/:uuid/published which will publish all language variants of the node. It is also possible to just publish specific language variants via /api/v1/:projectName/nodes/:uuid/languages/:languageTag/published. 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 version 1.0. It is also possible to retrieve detailed information about the published status via a GET request on /api/v1/:/nodes/:uuid/published.

Publishing node language variations requires the user to be assigned to a role which provides the publish permission.
{
  "availableLanguages" : {
    "de" : {
      "published" : false,
      "version" : {
        "uuid" : "9fab9def854a492fab9def854aa92fe3",
        "number" : "0.4"
      }
    },
    "en" : {
      "published" : true,
      "version" : {
        "uuid" : "6e090e41e8b14243890e41e8b1c24309",
        "number" : "3.0"
      },
      "publisher" : {
        "firstName" : "Joe",
        "lastName" : "Doe",
        "uuid" : "74445fcf29604d2b845fcf2960ed2b47"
      },
      "publishDate" : "2017-03-28T13:35:34.376Z"
    },
    "fr" : {
      "published" : false,
      "version" : {
        "uuid" : "d9a0f63c8ba84cb4a0f63c8ba81cb4df",
        "number" : "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 the language variants of a node can be taken offline via a DELETE request on /api/v1/:projectName/nodes/:uuid/published. Taking a node language variant with version 1.0 offline will just change the node’s publish state. Version 1.0 will still be available.

Reading Nodes

It is possible to load older versions by specifying the ?version parameter. Similarly the published version of can also be loaded using the parameter ?version=published or the draft version via ?version=draft.

By default nodes will be loaded using ?version=published. A nodes list thus may not contain your previously created node because it was not yet published.
Reading published nodes requires the user to be assigned to a role which grants the readpublished permission.

Permissions

Permissions are not version specific. Permissions apply to nodes and not to language variants.

Limitations

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

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.

[ {
  "name" : "content",
  "uuid" : "c0403866ca5f48be803866ca5f58be1c",
  "version" : 1
}, {
  "name" : "folder",
  "uuid" : "3062617e9b9247aba2617e9b9277ab44",
  "version" : 1
}, {
  "name" : "binary-data",
  "uuid" : "3440e65ccad64edc80e65ccad63edc12",
  "version" : 1
} ]

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

[ {
  "name" : "vcard",
  "uuid" : "77df33f13ada45889f33f13ada05887b",
  "version" : 2
}, {
  "name" : "geolocation",
  "uuid" : "04af30ce23934dfdaf30ce23938dfd88",
  "version" : 1
} ]

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 winder2016 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.

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

Image Manipulation

Images can be resized by appending the image manipulation query parameters on the binary node endpoint:

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

It is also possible to use the image manipulation in combination with the webroot endpoint:

Endpoint: /api/v1/:projectName/webroot/:path?width=220

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

Parameter Description

width

Target image width.

height

Target image height.

cropx

Crop area start x coordinate.

cropy

Crop area start y coordinate.

cropw

Crop area width.

croph

Crop area height.

Language Fallback

Nodes are translated into different languages. 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). Otherwise, the node will still be returned, but without fields.

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" : "71505ff1b7994d7c905ff1b7992d7c63",
  "creator" : {
    "uuid" : "58289325ef8746aaa89325ef8706aadf"
  },
  "created" : null,
  "editor" : {
    "uuid" : "58289325ef8746aaa89325ef8706aadf"
  },
  "edited" : null,
  "username" : "joe1",
  "emailaddress" : "joe1@nowhere.tld",
  "firstname" : "Joe",
  "lastname" : "Doe",
  "groups" : {
    "name" : [ "editors", "superEditors" ],
    "uuid" : [ "a00ccae23f0847138ccae23f085713af", "bd5d991c928842639d991c9288c26304" ]
  }
}

Groups

Endpoint: /api/v1/search/groups

{
  "name" : "adminGroup",
  "uuid" : "4f6cadc78d5a4c3bacadc78d5a4c3bce",
  "creator" : {
    "uuid" : "b2f1807746194d12b180774619fd12c5"
  },
  "created" : null,
  "editor" : {
    "uuid" : "b2f1807746194d12b180774619fd12c5"
  },
  "edited" : null
}

Roles

Endpoint: /api/v1/search/roles

{
  "name" : "adminRole",
  "uuid" : "5787f367f46f408687f367f46fb08684",
  "creator" : {
    "uuid" : "757fc1eea68e49dfbfc1eea68ea9df05"
  },
  "created" : null,
  "editor" : {
    "uuid" : "757fc1eea68e49dfbfc1eea68ea9df05"
  },
  "edited" : null
}

Nodes

Endpoint: /api/v1/search/nodes

{
  "uuid" : "fffe8f17566c45efbe8f17566c75ef1a",
  "editor" : {
    "uuid" : "a5f9e977a82b4f79b9e977a82b1f79cd"
  },
  "edited" : "1970-01-01T00:00:00Z",
  "creator" : {
    "uuid" : "a5f9e977a82b4f79b9e977a82b1f79cd"
  },
  "created" : "1970-01-01T00:00:00Z",
  "project" : {
    "name" : "dummyProject",
    "uuid" : "42e7204c37114b3ba7204c37116b3bb3"
  },
  "tags" : {
    "name" : [ "green", "red" ],
    "uuid" : [ "39481a40f201484d881a40f201d84d39", "1fed546ca2324f79ad546ca232ef792e" ]
  },
  "tagFamilies" : {
    "colors" : {
      "uuid" : "e00d13ee433c4a268d13ee433c0a2603",
      "tags" : [ {
        "name" : "green",
        "uuid" : "39481a40f201484d881a40f201d84d39"
      }, {
        "name" : "red",
        "uuid" : "1fed546ca2324f79ad546ca232ef792e"
      } ]
    }
  },
  "parentNode" : {
    "uuid" : "5520ff7944044ad4a0ff794404aad44c"
  },
  "language" : "de",
  "schema" : {
    "name" : "content",
    "uuid" : "18d091514e1c4afd9091514e1c2afd63",
    "version" : "0"
  },
  "fields" : {
    "date" : 1490708135,
    "string" : "The name value",
    "htmlList" : [ "some<b>html", "some<b>html", "some<b>html" ],
    "nodeList" : [ "c08877bd6e4a4f198877bd6e4a1f19a2", "c08877bd6e4a4f198877bd6e4a1f19a2", "c08877bd6e4a4f198877bd6e4a1f19a2" ],
    "number" : 0.146,
    "node" : "c08877bd6e4a4f198877bd6e4a1f19a2",
    "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" : [ 1490708135, 1490708135, 1490708135 ]
  },
  "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"
              }
            }
          ]
        }
      }
    }
  }
}

Projects

  • /api/v1/search/projects

{
  "name" : "dummyProject",
  "uuid" : "6ba7ffe4ec5f4ea7a7ffe4ec5f9ea793",
  "creator" : {
    "uuid" : "6eadaac84e9b4655adaac84e9be6555e"
  },
  "created" : null,
  "editor" : {
    "uuid" : "6eadaac84e9b4655adaac84e9be6555e"
  },
  "edited" : null
}

Tags

Endpoint: /api/v1/search/tags

{
  "name" : "red",
  "uuid" : "89a27aa65aef4fc3a27aa65aef4fc3de",
  "creator" : {
    "uuid" : "855e9bd327864b869e9bd327864b86ca"
  },
  "created" : null,
  "editor" : {
    "uuid" : "855e9bd327864b869e9bd327864b86ca"
  },
  "edited" : null,
  "tagFamily" : {
    "name" : "colors",
    "uuid" : "c5cb297cfff247778b297cfff2f77716"
  },
  "project" : {
    "name" : "dummyProject",
    "uuid" : "a9c5289eeb6d400a85289eeb6dd00a81"
  }
}

Tag Families

Endpoint: /api/v1/search/tagFamilies

{
  "name" : "colors",
  "uuid" : "8c914b6caba047e8914b6caba0a7e8bc",
  "creator" : {
    "uuid" : "6b02b9a648a6496a82b9a648a6b96aa7"
  },
  "created" : null,
  "editor" : {
    "uuid" : "6b02b9a648a6496a82b9a648a6b96aa7"
  },
  "edited" : null,
  "tags" : {
    "name" : [ "red", "green" ],
    "uuid" : [ "7119242a69324f0e99242a69329f0ea2", "371322fb7e7940f19322fb7e7990f11f" ]
  },
  "project" : {
    "name" : "dummyProject",
    "uuid" : "29b7eace13f94341b7eace13f9334162"
  }
}

Schemas

Endpoint: /api/v1/search/schemas

{
  "name" : "content",
  "description" : "Content schema",
  "uuid" : "0d0a246cec3343428a246cec33334250",
  "creator" : {
    "uuid" : "48a22b1b0ab046bfa22b1b0ab0f6bfd6"
  },
  "created" : null,
  "editor" : {
    "uuid" : "48a22b1b0ab046bfa22b1b0ab0f6bfd6"
  },
  "edited" : null
}

Microschemas

Endpoint: /api/v1/search/microschemas

{
  "uuid" : "3586ec37e65242df86ec37e65212dff3",
  "creator" : {
    "uuid" : "6c8ed133b80a48bc8ed133b80a18bcda"
  },
  "created" : null,
  "editor" : {
    "uuid" : "6c8ed133b80a48bc8ed133b80a18bcda"
  },
  "edited" : null,
  "name" : "geolocation"
}

Clustering

Clustering support is still in development.

It will be possible to use master/master replication for OrientDB. Clustering for the elasticsearch nodes and the vertx event message bus.

Administration UI

The Gentics Mesh Administration UI is an AngularJS single page application which uses the REST API to interface with Gentics Mesh. By default it can be reached via http://localhost:8080/mesh-ui/.

Configuration

The mesh-ui can be configured using the mesh-ui-config.js file.

(function(window, document) {

    /**
     * Settings which can be configured per app instance, without requiring the app be re-built from
     * source.
     */
    var meshUiConfig = {
        // The URL to the Mesh API
        apiUrl: '/api/v1/',

        // The ISO-639-1 code of the default language
        defaultLanguage: 'en',
        // The ISO-639-1 codes of the available languages
        availableLanguages: ['en', 'de'],

        // Provide an array or URLs for previewing nodes, in the following format:
        //
        // ```
        // {
        //   projectName: [
        //     // label: url
        //     { somePreview: 'http://some/url' },
        //     { otherPreview: 'http://someother/url' }
        //  ]
        // }
        // ```
        // When this option is used, a "preview" button will be available
        // in the node editor pane. Click it will POST the node data to the specified URL. The node will be
        // encoded as form data under the key "node", and its value will need to be de-serialized back into JSON
        // (e.g. using JSON.parse()). The "default" key will make the URls available to all projects.
        previewUrls: {
            default: [
                { default: 'https://httpbin.org/post' }
            ]
        },

        // A microschema control is a custom form component which can be used to render a
        // specific microschema, in place of the default form generator. For full documentation, please
        // see the example in `/microschemaControls/example/exampleControl.js`
        //
        // The `microschemaControlsLocation` may point to any location on the current server or even on
        // another server. Note that if serving microschema controls from a different server or port, you
        // must take CORS into consideration and set the Access-Control-Allow-Origin headers accordingly.
        microschemaControlsLocation: '/microschemaControls',
        microschemaControls: [
            // "geolocation/geolocationControl",
            // "example/exampleControl"
        ],

        // List any plugins to be loaded and made available to the Aloha editor.
        // (For available plugins see http://www.alohaeditor.org/guides/plugins.html)
        // If left empty, the following default plugins will be used:
        //  'common/autoparagraph',
        //  'common/contenthandler',
        //  'common/format',
        //  'common/highlighteditables',
        //  'common/list',
        //  'common/paste',
        //  'common/table',
        //  'common/ui'
        // plus a custom link plugin (mesh/mesh-link) for linking to other Mesh nodes.
        alohaPlugins: [],

        // Custom settings object for the Aloha editor. If left empty, the default configuration
        // will be used.
        alohaSettings: {}
    };


    window.meshUiConfig = meshUiConfig;

})(window, document);

Preview handling

The mesh ui will provide a preview button when editing nodes. A post request to a configureable url is being dispatchen when the button will be 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.

JAVA REST client

You can add the following maven dependency and repository to your project to get the mesh rest client.

…
	<dependency>
		<artifactId>mesh-rest-client</artifactId>
		<groupId>com.gentics.mesh</groupId>
		<version>${mesh.version}</version>
	</dependency>
…
	<repositories>
		<repository>
			<id>maven.gentics.com</id>
			<name>Gentics Maven Repository</name>
			<url>https://maven.gentics.com/maven2</url>
			<releases>
				<enabled>true</enabled>
			</releases>
			<snapshots>
				<enabled>true</enabled>
			</snapshots>
		</repository>
	</repositories>
…

Usage:

	MeshRestClient client = MeshRestClient.create("localhost", 8080, vertx, BASIC_AUTH);
	client.setLogin("username", "password");
	client.login().toCompletable().await();

	client.findNodes("demo", new NodeRequestParameter().setExpandAll(true).setLanguages("en")).setHandler(rh -> {
		if (rh.succeeded()) {
			NodeListResponse list = rh.result();
			for(NodeResponse nodeResponse : list.getData()) {
				System.out.println(nodeResponse.getUuid());
				System.out.println(nodeResponse.getFields().getStringField("name").getString());
			}
		} else {
			rh.cause().printStackTrace();
		}
	});

License

  • Gentics Mesh is published under a commercial license. License Terms

  • GraphiQL is owned and developed by Facebook Inc.