Jahia provides a REST API, mostly for rendering, but some other services are available as well such: login, logout, content creation & updating and searching.
You can find an example of some REST API calls in the file modules/test/rest/jqueryfind.html. To test this file, make sure you start & configure your Jahia, and then point your browser to the following URL :
http://localhost:8080/modules/test/rest/jqueryfind.html
URL : /cms/login
Method : POST
Parameters :
| Name | Mandatory | Description |
| username | yes | The username of the user that you want to login |
| password | yes | The user's password |
| redirectActive | no | If set to "true" or not set, the login servlet will redirect to the home page after successful authentication. If you are using AJAX calls you should set this to "false". |
| doLogin | yes | Should always be set to "true" otherwise login will not work |
| redirect | no | Allows you to specify another URL to redirect after successful login |
URL : /cms/logout
Method : POST
| Name | Mandatory | Description |
| redirectActive | no | If set to "true" or not set, the login servlet will redirect to the home page after successful authentication. If you are using AJAX calls you should set this to "false". |
| redirect | no | Allows you to specify another URL to redirect after successful login |
TBD
The render servlet can either be used to render content by accessing it with a GET method, or can also be used to add content to different workspaces by using a POST method and special parameters. You can also delete content using DELETE method, or update content using POST or PUT.
URL : /cms/render/WORKSPACE/LANGUAGE/CONTENT_PATH
Method : POST
Request headers : see response format section below.
| Name | Mandatory | Description |
| jcrNodeType | yes | Define the type of node you want to create. |
| jcrNodeName | no | If defined we will create a node with this name (or use it as a prefix for the name. If not define you can call : /cms/render/WORKSPACE/LANGUAGE/CONTENT_PATH/* To create a subnode at the specified path using the nodetype for name. |
| jcrNewNodeOutputFormat | no | Define at which format the newly created node will be returned, HTML by default, JSON is another possible value, or any type of output you have define in your templates. |
| jcrRedirectTo | no | If defined will redirect to the specified URL instead of the newly created node. |
| jcrMethodToCall | no | For HTML form to override the method called, this allow to delete content with a simple POST form instead of send a DELETE HTTP request |
| jcrAutoCheckin | no | Allow to force versioning of the newly created content. |
| jcrTargetDirectory | no | If you have multipart form, this will be the location where the content is uploaded |
| jcrVersion | no | If "true" activate the versionning on the posted content (works only for files) |
| jcr:mixinTypes | no | Allow you to set a mixin on the new node |
All AJAX JSON requests should have the following headers set :
accept: application/json x-requested-with : XMLHttpRequest
The second header should be set for you when accessing the API through a browser, but if you are using the REST API through an HttpClient call or even another external client software (such as a mobile device for example), be sure that both these headers are set, otherwise it will default to HTML feedback.
In the case of a file upload, when using AJAX requests (by setting the headers as described in the previous section), you actually have to perform two requests. The first request will be a multipart form upload and will save either in the current users' "files" directory, or if the "targetDirectory" property was set it will store the uploaded files there. The response is a JSON object with a "uuids" array property that contains string of the identifiers of all the created file nodes in the repository.
The second request can then use the UUIDs returned by the first AJAX request to set references to the new file nodes.
If a file already exists at the upload target, it will be updated, and if versioning is activated (see the version parameter above), it will create a new version before updating the file.
In the case of a regular POST method, the default response format is HTML. This format may be changed to JSON by setting up the appropriate request headers (see below).
In the case of HTML we will render the newly created or updated node with its default template (unless you have specified a different template using the newNodeOutputFormat parameter).
In order to change the response format to JSON, you must set the following headers : "accept" = "application/json" and "x-requested-with" = "XMLHttpRequest".
<form action="<c:url value='${url.base}${currentNode.path}/*'/>" method="post">
<input type="hidden" name="jcrNodeType" value="jnt:post"/>
<input type="hidden" name="jcrRedirectTo" value="<c:url value='${url.base}${renderContext.mainResource.node.path}'/>"/>
<%-- Define the output format for the newly created node by default html or by jcrRedirectTo--%>
<input type="hidden" name="jcrNewNodeOutputFormat" value="html"/>
<fieldset>
<p class="field">
<input value="<c:if test="${not empty currentNode.children}"> Re:</c:if>${currentNode.propertiesAsString['threadSubject']}" type="text" size="35" id="forum_site" name="jcr:title"
tabindex="1"/>
</p>
<p class="field">
<textarea rows="7" cols="35" id="jahia-forum-thread-${currentNode.UUID}" name="content" tabindex="2"></textarea>
</p>
<p class="forum_button">
<input type="reset" value="Reset" class="button" tabindex="3"/>
<input type="submit" value="Submit" class="button" tabindex="4"/>
</p>
</fieldset>
</form>This will create a new comments in a thread of a forum. And after submission we want to redisplay the curren thread, this is why we used the jcrRedirectTo parameter.
<form action="<c:url value='${url.base}${currentNode.path}'/>" method="post"
id="jahia-forum-post-delete-${currentNode.UUID}">
<input type="hidden" name="jcrRedirectTo" value="<c:url value='${url.base}${renderContext.mainResource.node.path}'/>"/>
<%-- Define the output format for the newly created node by default html or by jcrRedirectTo--%>
<input type="hidden" name="jcrNewNodeOutputFormat" value="html"/>
<input type="hidden" name="jcrMethodToCall" value="delete"/>
</form>
<a title="<fmt:message key='delete.post'/>" href="#"
onclick="document.getElementById('jahia-forum-post-delete-${currentNode.UUID}').submit();"><span><fmt:message key="delete.post"/></span>This example shows how to write a simple form to delete a content with a simple link.
The find servlet can be used to query content inside the Jahia JCR repository. It provides a lightweight but very powerful interface to retrieve content anywhere inside the content repository. Please note that if you need to search for users or groups, you should use the findPrincipal servlet instead, since it integrates with external principal repositories such as LDAP.
URL : /cms/find/WORKSPACE/LANGUAGE
Method : POST or GET
Parameters :
| Name | Mandatory | Description |
| query | yes | The JCR query to execute. You can reference request parameters in your query by using the following syntax : $paramName which will look for a request parameter called "paramName" |
| language | no | The JCR language used in the query, for example "JCR-SQL2" or "xpath" Defaults to "JCR-SQL2" |
| limit | no | The maximum number of results to return. Defaults to 0 that does not limit the results. |
| offset | no | The 0-index based offset to start results with. Defaults to 0. |
| depthLimit | no | The depth of the result tree. If not set it defaults to "1". If you have deep content tree hierarchies you might want to limit result depth to avoid performance issues. |
| escapeColon | no | If set to true, the ':' in the node property name will be replaced '_'. Defaults to false. |
| propertyMatchRexexp | no | The value you specify here will be used to match properties in the result set, and will build a matchingProperties JSON list that will let you known which properties have matched. This is especially useful when using fulltext search, since the JCR doesn't indicate which property has matched the criteria. The value you specify must comply with the JDK Pattern Regexp syntax. |
| removeDuplicatePropValues | no | If activated, it will filter the matched properties (that were matched using the propertyMatchRegexp above parameter) to make sure only one node per property value is returned. This is useful when building unique list of property values for auto-completion. Defaults to false. |
http://localhost:8080/cms/find/default/en ?q=t &limit=10 &query=%2Fjcr%3Aroot%2Fsites%2FmySite%2Ftags%2F%2Felement(*%2C+jnt%3Atag)%5Bjcr%3Acontains(.%2C'%7B%24q%7D*')%5D%2F%40j%3Anodename &language=xpath &escapeColon=false &propertyMatchRegexp=%7B%24q%7D.* &removeDuplicatePropValues=false
In the above example, the values are encoded so that makes a bit harder to read. Here are the unencoded values :
query = /jcr:root/sites/mySite/tags//element(*, jnt:tag)[jcr:contains(.,'{$q}*')]/@j:nodename
propertyMatchRegexp = {$q}.*One important thing is to now the $q marker that will actually be replaced with the value of the "q" request parameter specified in the request. This makes it easy to integrate with JQuery plugins that might use specific named request parameters.
Content-Length:1721
Content-Type:application/json;charset=UTF-8
Date:Fri, 26 Feb 2010 13:31:38 GMT
Server:Apache-Coyote/1.1
[
{
"jcr:score": "1366",
"node": {
"index": 1,
"jcr:createdBy": "root",
"jcr:baseVersion": "/repository/default/jcr:system/jcr:versionStorage/5b/92/d7/5b92d76a-ee40-4b17-87e6-911a38db2ddb/jcr:rootVersion",
"jcr:versionHistory": "/repository/default/jcr:system/jcr:versionStorage/5b/92/d7/5b92d76a-ee40-4b17-87e6-911a38db2ddb",
"depth": 4,
"jcr:lastModifiedBy": "root",
"primaryNodeType": "jnt:tag",
"j:nodename": "tag1",
"j:originWS": "default",
"jcr:isCheckedOut": "true",
"jcr:lastModified": "2010-02-26T12:14:14.502+01:00",
"matchingProperties": [
"j:nodename",
"jcr:isCheckedOut"
],
"jcr:created": "2010-02-26T12:14:14.397+01:00",
"j:fullpath": "/sites/mySite/tags/tag1",
"jcr:uuid": "5b92d76a-ee40-4b17-87e6-911a38db2ddb",
"jcr:primaryType": "jnt:tag",
"identifier": "5b92d76a-ee40-4b17-87e6-911a38db2ddb",
"path": "/sites/mySite/tags/tag1"
},
"j:nodename": "tag1",
"jcr:path": "/sites/mySite/tags/tag1"
},
{
"jcr:score": "1366",
"node": {
"index": 1,
"jcr:createdBy": "root",
"jcr:baseVersion": "/repository/default/jcr:system/jcr:versionStorage/ab/63/bb/ab63bb78-8708-48aa-a040-82eee22ae5d7/jcr:rootVersion",
"jcr:versionHistory": "/repository/default/jcr:system/jcr:versionStorage/ab/63/bb/ab63bb78-8708-48aa-a040-82eee22ae5d7",
"depth": 4,
"jcr:lastModifiedBy": "root",
"primaryNodeType": "jnt:tag",
"j:nodename": "tag2",
"j:originWS": "default",
"jcr:isCheckedOut": "true",
"jcr:lastModified": "2010-02-26T12:14:18.570+01:00",
"matchingProperties": [
"j:nodename",
"jcr:isCheckedOut"
],
"jcr:created": "2010-02-26T12:14:18.477+01:00",
"j:fullpath": "/sites/mySite/tags/tag2",
"jcr:uuid": "ab63bb78-8708-48aa-a040-82eee22ae5d7",
"jcr:primaryType": "jnt:tag",
"identifier": "ab63bb78-8708-48aa-a040-82eee22ae5d7",
"path": "/sites/mySite/tags/tag2"
},
"j:nodename": "tag2",
"jcr:path": "/sites/mySite/tags/tag2"
}
]In the above JSON response, it is important to node the following properties :
This servlet is dedicated to searching for users or groups, with the particularity of being able to search in external principal repositories connected with Jahia, such as an LDAP repository. Note that the query and result formats are quite different to the default find servlet, because they are not representing JCR nodes but principal data structures.
URL : /cms/findPrincipal
Method : POST or GET
Parameters :
| Name | Mandatory | Description |
| principalType | yes | The type of principal you wish to query for. The accepted values are "users" or "groups" a request parameter called "paramName" |
| siteKey | yes (if searching for groups | If you have set the principalType parameter to "groups", you will be required to specify a value for the siteKey parameter, which is the site in which you want to search for the groups. |
| wildcardTerm | no | If this parameter is specified, it will be used to search for the value specified in any principal property. If you prefer to search for specific properties, you must specify them separately in the HTTP request parameters. You can use the $paramName syntax to reference other request parameters. For example $q will be replaced by the value of a parameter called "q" if it is found. If it is not found the marker will not be replaced. |
| propertyMatchRexexp | no | The value you specify here will be used to match properties in the result set, and will build a matchingProperties JSON list that will let you known which properties have matched. This is especially useful when using fulltext search, since the JCR doesn't indicate which property has matched the criteria. The value you specify must comply with the JDK Pattern Regexp syntax. |
| removeDuplicatePropValues | no | If activated, it will filter the matched properties (that were matched using the propertyMatchRegexp above parameter) to make sure only one node per property value is returned. This is useful when building unique list of property values for auto-completion. Defaults to false. |
| includeCriteriaNames | no | A comma seperated list of parameter names that should be used to create the criterias for the search. |
| any other parameter name | no | If you specify another other parameter other than the above reserved ones, the servlet will interpret them as property names that have to to be search for the specified values. You can use the $paramName syntax to reference other request parameters. For example $q will be replaced by the value of a parameter called "q" if it is found. If it is not found the marker will not be replaced. By default the servlet will use all the other found parameter names, which might not be what you expect. You should use the includeCriteriaNames to specify which criteria should be used |
http://localhost:8080/cms/findPrincipal?principalType=users&wildcardTerm=steve
[
{
"userProperties": "{j:published=true, j:nodename=sjobs, j:originWS=default, jcr:createdBy= system , j:external=false, j:firstName=Steve, jcr:primaryType=jnt:user, j:lastPublished=2010-06-16T16:13:34.094+02:00, j:email=, j:password=943+/myvMchk4TM1T11nKHx2u7g=, j:lastName=Jobs, jcr:baseVersion=164174a4-1ba0-4e3b-8143-119c9546be6c, j:lastPublishedBy= system root, jcr:created=2010-06-16T16:13:33.698+02:00, jcr:versionHistory=d17e5352-4909-48ef-94ef-e5957f741512, jcr:uuid=662cdfed-e674-4dff-85ee-dadb19243f5e, j:fullpath=/users/sjobs, jcr:isCheckedOut=true, j:checkinDate=2010-06-16T16:13:34.094+02:00, jcr:lastModified=2010-06-16T16:14:01.670+02:00, jcr:lastModifiedBy= system , j:organization=}",
"homepageID": -1,
"username": "sjobs",
"providerName": "jcr",
"userKey": "{jcr}sjobs",
"root": false,
"external": false,
"name": "sjobs",
"class": "class org.jahia.services.usermanager.jcr.JCRUser",
"properties": {
"j:firstName": "Steve",
"jcr:created": "2010-06-16T16:13:33.698+02:00",
"j:external": "false",
"j:originWS": "default",
"j:published": "true",
"jcr:lastModified": "2010-06-16T16:14:01.670+02:00",
"j:lastPublishedBy": " system root",
"j:checkinDate": "2010-06-16T16:13:34.094+02:00",
"jcr:createdBy": " system ",
"j:nodename": "sjobs",
"jcr:versionHistory": "d17e5352-4909-48ef-94ef-e5957f741512",
"jcr:lastModifiedBy": " system ",
"jcr:uuid": "662cdfed-e674-4dff-85ee-dadb19243f5e",
"preferredLanguage": "en",
"jcr:baseVersion": "164174a4-1ba0-4e3b-8143-119c9546be6c",
"j:lastName": "Jobs",
"jcr:isCheckedOut": "true",
"j:password": "943+/myvMchk4TM1T11nKHx2u7g=",
"j:lastPublished": "2010-06-16T16:13:34.094+02:00",
"j:organization": "",
"jcr:primaryType": "jnt:user",
"j:fullpath": "/users/sjobs",
"j:email": ""
},
"identifier": "662cdfed-e674-4dff-85ee-dadb19243f5e",
"passwordReadOnly": false
}
]