Chapter 33. The Nuxeo Restlet API

Table of Contents

33.1. Restlet Integration
33.1.1. Restlet types in Nuxeo 5
33.1.2. Restlet URL and parameters mapping
33.1.3. Contributing a new restlet
33.2. Nuxeo default restlets
33.2.1. Browse restlet
33.2.2. Export restlet
33.2.3. Lock restlet
33.2.4. Plugin upload restlet
33.3. Nuxeo RestPack
33.3.1. Installing the RestPack
33.3.2. Restlets included in the RestPack
33.4. Nuxeo WebEngine Restlets

Nuxeo integrates the Restlet framework to provide an easy way to contribute new REST API on top of the platform.

33.1. Restlet Integration

The REST API provides an easy way to call Nuxeo services from an external application. Even if REST is a very simple concept, we choose to leverage an existing REST framework to provide an REST API on top of Nuxeo. The selected framework is Restlets (http://www.restlet.org/) that provides a lightweight and flexible REST framework. The Nuxeo REST integration API (org.nuxeo.ecm.platform.ui.web.restAPI) provides:

  • A runtime service to contribute new restlets

  • Base classes for new restlets

  • A main servlet that handles the routing between restlets

  • An integration with the Nuxeo API and Seam context

To implement a restlet you simply have to implement the Restlet interface.

33.1.1. Restlet types in Nuxeo 5

Nuxeo 5 defines 3 different types of restlets :

  • Stateless restlets

    No integration with Seam and no state management. This is the original logic of Restlet.

    You can use BaseStalessNuxeoRestlet as base class that provides helpers for accessing main services (like the repository).

  • Seam-aware restlets

    For restlet declared as Seam-aware, the Nuxeo Restlet servlet initializes the Seam context before executing the restlet. Thanks to this initialization your restlet can use injection (@In) to access the Seam context. This solution gives you the possibility of using existing Seam components. You don't have to use Service Platform API to access the service since you can access Seam delegates for that.

    You can use BaseNuxeoRestlet that provides helper API for error handling, security and URL management.

  • Conversation-aware restlets

    The are Seam restlets that are tied to a Seam conversation. For these restlets, the Seam context initialization is done in order to setup the current Conversation. Conversational restlets must be called with a conversationId as parameter.

    Conversational restlet can be used if you need to access the current Seam context associated with a browser session. Typically this is what is used by the Firefox helper to upload files.

    You can use BaseNuxeoRestlet that provides helper API for error handling, security and URL management.

33.1.2. Restlet URL and parameters mapping

All restlets are bound to one or more URL patterns. These URLs patterns are used by Nuxeo RestletServlet to determine which restlet needs to receive the call.

When defining URLs you can use {} to have parts of the URL that will be converted as parameters.

For example :

/{repo}/{docid}/{filename}/upload

will define a URL pattern with 4 parts and you will have access from withing your code to 3 parameters: repo, docId and filename.

These parameters can be used via Restlet API :

req.getAttributes().get("repo");

You can also access the standard GET/POST parameters via

req.getResourceRef().getQueryAsForm().getFirstValue("SomeParameter");

33.1.3. Contributing a new restlet

Contributing a new restlet is quite simple.

The first thing to do is to write a new restlet: you can either implement the Restlet Interface "by hand" or just inherit from BaseNuxeoRestlet or BaseStatelessNuxeoRestet.

Once your class is written, you need to contribute to the restlets extension point exposed by org.nuxeo.ecm.platform.ui.web.restAPI.service.PluggableRestletService.

<?xml version="1.0"?>
<component name="org.nuxeo.ecm.platform.ui.web.restAPI.contrib">

  <extension
      target="org.nuxeo.ecm.platform.ui.web.restAPI.service.PluggableRestletService"
      point="restlets">
    <restletPlugin
        name="upload"
        class="org.nuxeo.ecm.platform.ui.web.restAPI.UploadRestlet"
        enabled="true"
        useSeam="true"
        useConversation="false">
      <urlPatterns>
        <urlPattern>/{repo}/{docid}/{filename}/upload</urlPattern>
      </urlPatterns>
   </restletPlugin>
   ...

The useSeam and useConversation flags define how the Nuxeo Restlet servlet will handle the call.

33.2. Nuxeo default restlets

Nuxeo comes by default with very simple restlet that can be seen as samples.

33.2.1. Browse restlet

The Browse restlet is a simple way to navigate into the repository via REST.

A typical call to list content of default repository would be : http://127.0.0.1:8080/nuxeo/restAPI/default/*/browse

If you need to browse the document 95ce52b2-6959-4afa-bc63-396096b376b4 a typical call would be : http://127.0.0.1:8080/nuxeo/restAPI/default/95ce52b2-6959-4afa-bc63-396096b376b4/browse

Typical output for this restlet would be:

<document title="2fbf878d-9c2f-42c6-acbb-ea339ce15615"
          type="Root"
          id="2fbf878d-9c2f-42c6-acbb-ea339ce15615"
          url="/default/2fbf878d-9c2f-42c6-acbb-ea339ce15615">
  <document title="Default domain"
            type="Domain"
            id="95ce52b2-6959-4afa-bc63-396096b376b4"
            url="/default/95ce52b2-6959-4afa-bc63-396096b376b4"/>
</document>

This restlet uses Seam in order to have documentManager injected (this is not a need but rather a simple way of accessing the repository without using the Service API)

Browse restlet registration looks like this:

<restletPlugin
    name="browse"
    class="org.nuxeo.ecm.platform.ui.web.restAPI.BrowseRestlet"
    enabled="true"
    useSeam="true">
  <urlPatterns>
    <urlPattern>/{repo}/{docid}/browse</urlPattern>
  </urlPatterns>
</restletPlugin>

33.2.2. Export restlet

This restlet is a simple REST frontend on top of IO core service. This can be used to export a document or a document tree as XML.

A typical call would be :

  • http://127.0.0.1:8080/nuxeo/restAPI/default/2fbf878d-9c2f-42c6-acbb-ea339ce15615/export

    to export the document 2fbf878d-9c2f-42c6-acbb-ea339ce15615 as XML

  • http://127.0.0.1:8080/nuxeo/restAPI/default/2fbf878d-9c2f-42c6-acbb-ea339ce15615/export?format=ZIP

    to export the document 2fbf878d-9c2f-42c6-acbb-ea339ce15615 as a ZIP archive

  • http://127.0.0.1:8080/nuxeo/restAPI/default/2fbf878d-9c2f-42c6-acbb-ea339ce15615/exportTree

    to export the document 2fbf878d-9c2f-42c6-acbb-ea339ce15615 and all its children as a Zip Archive

  • http://127.0.0.1:8080/nuxeo/restAPI/default/2fbf878d-9c2f-42c6-acbb-ea339ce15615/exportTree?format=XML

    to export the document 2fbf878d-9c2f-42c6-acbb-ea339ce15615 and all its children as XML

This restlet uses Seam in order to have documentManager injected (this is not a need but rather a simple way of accessing the repository without using the Service API)

Export restlet registration looks like this:

<restletPlugin
    name="export"
    class="org.nuxeo.ecm.platform.ui.web.restAPI.ExportRestlet"
    enabled="true"
    useSeam="true">
  <urlPatterns>
    <urlPattern>/{repo}/{docid}/export</urlPattern>
    <urlPattern>/{repo}/{docid}/exportSingle</urlPattern>
    <urlPattern>/{repo}/{docid}/exportTree</urlPattern>
  </urlPatterns>
</restletPlugin>

33.2.3. Lock restlet

This restlet provide a REST API for Lock Management.

A typical call would be:

  • GET http://127.0.0.1:8080/nuxeo/restAPI/default/2fbf878d-9c2f-42c6-acbb-ea339ce15615/Locking/status

    to get Lock status of the document 2fbf878d-9c2f-42c6-acbb-ea339ce15615

  • GET http://127.0.0.1:8080/nuxeo/restAPI/default/2fbf878d-9c2f-42c6-acbb-ea339ce15615/Locking/lock

    or

    LOCK http://127.0.0.1:8080/nuxeo/restAPI/default/2fbf878d-9c2f-42c6-acbb-ea339ce15615/Locking

    to Lock status the document 2fbf878d-9c2f-42c6-acbb-ea339ce15615

  • GET http://127.0.0.1:8080/nuxeo/restAPI/default/2fbf878d-9c2f-42c6-acbb-ea339ce15615/Locking/unlock

    or

    UNLOCK http://127.0.0.1:8080/nuxeo/restAPI/default/2fbf878d-9c2f-42c6-acbb-ea339ce15615/Locking

    to Unlock status the document 2fbf878d-9c2f-42c6-acbb-ea339ce15615

This restlet is stateless and uses Nuxeo Service API

Lock restlet registration looks like this

<restletPlugin
    name="locking"
    class="org.nuxeo.ecm.platform.ui.web.restAPI.LockingRestlet"
    enabled="true"
    useSeam="false"
    useConversation="false">
  <urlPatterns>
    <urlPattern>/{repo}/{docid}/Locking</urlPattern>
  </urlPatterns>
</restletPlugin>

33.2.4. Plugin upload restlet

This restlet provides a REST API for file upload that is used by the Firefox helper.

A typical call would be:

  • POST http://127.0.0.1:8080/nuxeo/restAPI/default/e5125b5e-8b9e-43bd-8959-7e7e5caf2a1b/pluginUpload/myfolder/myfile

    to upload a file

This restlet uses Seam conversation.

pluginUpload restlet registration looks like this

<restletPlugin
    name="pluginUpload"
    class="org.nuxeo.ecm.platform.ui.web.restAPI.PluginUploadRestlet"
    enabled="true"
    useSeam="true"
    useConversation="true">
  <urlPatterns>
    <urlPattern>/{repo}/{docid}/pluginUpload</urlPattern>
  </urlPatterns>
</restletPlugin>

33.3. Nuxeo RestPack

The RestPack is an additional component for Nuxeo EP that provides additional restlets on top of Nuxeo Services.

The primary goal of the RestPack is to provide the needed RestAPI to build simple JSR168 portlets (like search portlets) that communicate with Nuxeo via HTTP/XML.

33.3.1. Installing the RestPack

You can download the RestPack from Nuxeo download site or build it from source.

To deploy the module, just copy the jar file in nuxeo.ear/system folder and restart you JBoss

33.3.2. Restlets included in the RestPack

33.3.2.1. Vocabulary Restlet

The Vocabulary restlet exports as XML the content of a given vocabulary

Sample call :

GET http://127.0.0.1:8080/nuxeo/restAPI/vocabulary/{vocName}/

parameters

  • {vocName}

    Name of the vocabulary to export, must be last part of QueryPath

  • lang

    GET (QueryString) parameter used to set language used to generate the labels

Sample calls

  • http://127.0.0.1:8080/nuxeo/restAPI/vocabulary/subject?lang=en

    <entries>
    <entry id="arts" label="label.directories.subject.arts" translatedLabel="Arts"/>
    <entry id="business" label="label.directories.subject.business" translatedLabel="Business"/>
    <entry id="computers" label="label.directories.subject.computers" translatedLabel="Computers"/>
    ...
    
  • http://127.0.0.1:8080/nuxeo/restAPI/vocabulary/continent_country?lang=en

    <entries>
    <entry id="africa" label="label.directories.continent.africa" translatedLabel="Africa">
    <entry id="Algeria" label="label.directories.country.Algeria" translatedLabel="Algeria" parent="africa"/>
    <entry id="Angola" label="label.directories.country.Angola" translatedLabel="Angola" parent="africa"/>
    <entry id="Benin" label="label.directories.country.Benin" translatedLabel="Benin" parent="africa"/>
    <entry id="Botswana" label="label.directories.country.Botswana" translatedLabel="Botswana" parent="africa"/>
    <entry id="Burkina_Faso" label="label.directories.country.Burkina_Faso" translatedLabel="Burkina Faso" parent="africa"/>
    <entry id="Burundi" label="label.directories.country.Burundi" translatedLabel="Burundi" parent="africa"/>
    <entry id="Cameroon" label="label.directories.country.Cameroon" translatedLabel="Cameroon" parent="africa"/>
    ...

33.3.2.2. Syndication Restlet

Export as RSS or ATOM the list of children document of the targeted container

Sample call:

http://127.0.0.1:8080/nuxeo/restAPI/{repoId}/{docId}/{format}

Parameters:

  • {repoId}

    Name of the target repository (use default on a standard installation)

  • {docId}

    DocumentRef of the target container (use the docId present in the standard nuxeo URL when browsing the webapp)

  • {format}

    Defines the syndication format: rss or atom

33.3.2.3. Workflow Tasks Restlet

Export user's workflow tasks as XML or ATOM

Sample call:

http://127.0.0.1:8080/nuxeo/restAPI/workflowTasks/{repoId}/?format=XML/ATOM

Parameters:

  • {repoId}

    Name of the target repository (use default on a standard installation)

  • format

    Defines the export format: xml or atom

Sample call:

http://127.0.0.1:8080/nuxeo/restAPI/workflowTasks/default/?format=xml

<nxt:tasks>
 <nxt:category category="None">
  <nxt:task name="review" workflowType="document_review_approbation" author="Administrator" startDate="2007-10-09 11:10:41"/>
 </nxt:category>
</nxt:tasks>

33.3.2.4. Query for Workflow Tasks Restlet

Export user's workflow tasks that match the query as XML or ATOM

Sample call:

http://127.0.0.1:8080/nuxeo/restAPI/queryForWorkflowTask/{repoId}/?format=XML/ATOM&workflowRequest=author&comparisonType=0/1&workItemFromUser=true/false&canManage=true/false

Parameters:

  • {repoId}

    Name of the target repository (use default on a standard installation)

  • format

    Defines the export format: xml or atom

  • workflowRequest

    Defines the workflow item attribute to compare for the query. Please refer to the WorkItem Filter.

  • comparisonType

    Defines the type of comparison. Please refer to the WorkItem Filter.

  • workItemFromUser

    If is true add filter that match WorkItem initiated by the user

  • canManage

    If true add filter that match workItems that the participant has a direct action to perform

Sample call:

http://127.0.0.1:8080/nuxeo/restAPI/workflowTasks/default/?format=xml

<nxt:tasks>
 <nxt:category category="None">
  <nxt:task name="review" workflowType="document_review_approbation" author="Administrator" startDate="2007-10-09 11:10:41"/>
 </nxt:category>
</nxt:tasks>

http://localhost:8080/nuxeo/restAPI/queryForWorkflowTask/default/?workflowRequest=author&comparisonType=0&workItemFromUser=true

Get work item tasks that the user initiate and is pending for the next user.

33.3.2.5. QueryModel Restlet

Execute a search via QueryModel and returns DocumenList as XML/RSS/ATOM/JSON

Sample call :

http://127.0.0.1:8080/nuxeo/restAPI/execQueryModel/{queryModelName}

Parameters:

  • {queryModelName}

    Name of the QueryModel to execute

  • format

    Defines the export format: XML, Atom, RSS or JSON. This parameter is set as a QueryString parameter

  • page

    Defines the page number you want in the result. This parameter is set as a QueryString parameter

  • ascending

    Defines ordering ascending: true/false. This parameter is set as a QueryString parameter

  • criteria

    Defines ordering columns used for sorting. This parameter is set as a QueryString parameter

  • columns

    Defines the columns you want to be included in the resultset. This parameter is set as a QueryString parameter

    This parameter is a simple string containing schema.fieldName tokens separated by "," . The only special field is url. Default value is : dublincore.title,dublincore.description,url

  • QueryModel parameters

    For stateless QueryModels, you have to specify the parameters via QP1, QP2 ... (only ordering is important)

    The value $USER is automatically replaced by the name of the current User :

    http://127.0.0.1:8080/nuxeo/restAPI/execQueryModel/USER_DOCUMENTS?QP1=$USER

    For stateful QueryModels, you have to specify the parameters as fieldName=FieldValue

Sample call:

http://127.0.0.1:8080/nuxeo/restAPI/execQueryModel/USER_DOCUMENTS?QP1=$USER&format=JSON

[
 {
  "title": "nouveau-fichier",
  "description": null,
  "url": "nxdoc/default/452c122d-07de-422b-b448-b0fef9534a62/view_documents",
  "id": "452c122d-07de-422b-b448-b0fef9534a62"
 },
 {
  "title": "Setup",
  "description": null,
  "url": "nxdoc/default/ae03f7bf-9967-4b5b-b37b-807fd40a6ec7/view_documents",
  "id": "ae03f7bf-9967-4b5b-b37b-807fd40a6ec7"
 },
 {
  "title": "cps",
  "description": null,
  "url": "nxdoc/default/2bad93ca-188f-4ea0-a585-9540a6ed6581/view_documents",
  "id": "2bad93ca-188f-4ea0-a585-9540a6ed6581"
 },
 {
  "title": "testMe",
  "description": null,
  "url": "nxdoc/default/e4de81a9-95e8-49ff-9146-e020f99b8bb8/view_documents",
  "id": "e4de81a9-95e8-49ff-9146-e020f99b8bb8"
 } ... ] 

http://127.0.0.1:8080/nuxeo/restAPI/execQueryModel/USER_DOCUMENTS?QP1=$USER&format=XML&page=1

<results>
<pages pages="3" pageNumber="1"/>
<document id="a3154f03-6baa-4d7d-8bac-579d52a8d304" title="ssl-uil2-service"
    url="nxdoc/default/a3154f03-6baa-4d7d-8bac-579d52a8d304/view_documents"/>
<document id="e2b26d9a-9140-44f1-ae23-4ad7866911c0" title="build"
    url="nxdoc/default/e2b26d9a-9140-44f1-ae23-4ad7866911c0/view_documents"/>
<document id="bf7de6df-bca1-4d29-8e26-5019ced696fd" title="jboss-service"
    url="nxdoc/default/bf7de6df-bca1-4d29-8e26-5019ced696fd/view_documents"/>
<document id="439a11e8-642d-41f7-ae0f-4ef4d7303d79" title="postgres-jdbc2-service"
    url="nxdoc/default/439a11e8-642d-41f7-ae0f-4ef4d7303d79/view_documents"/>
<document id="467745db-565d-4350-953f-b2fa03733406" title="oil-service"
    url="nxdoc/default/467745db-565d-4350-953f-b2fa03733406/view_documents"/>
<document id="44a2441e-e265-4fee-ad17-9ec24245cccf" title="jbossmq-state"
    url="nxdoc/default/44a2441e-e265-4fee-ad17-9ec24245cccf/view_documents"/>
<document id="8d7e3077-a3be-4d6c-806c-aa97816821e2" title="oracle-jdbc2-service"
    url="nxdoc/default/8d7e3077-a3be-4d6c-806c-aa97816821e2/view_documents"/>
<document id="b431ad04-3439-441e-826b-48b5f0f0c1c8" title="as400-jdbc2-service"
    url="nxdoc/default/b431ad04-3439-441e-826b-48b5f0f0c1c8/view_documents"/>
<document id="e146c6b2-a315-4788-9bbe-5f1fc79c18ac" title="mssql-jdbc2-service"
    url="nxdoc/default/e146c6b2-a315-4788-9bbe-5f1fc79c18ac/view_documents"/>
<document id="b109a672-5ebd-4a01-8a86-79e2430c2f07" title="file-state-service"
    url="nxdoc/default/b109a672-5ebd-4a01-8a86-79e2430c2f07/view_documents"/>
</results> 

http://127.0.0.1:8080/nuxeo/restAPI/execQueryModel/USER_DOCUMENTS?QP1=$USER&format=XML&page=1&columns=common.icon,dublincore.title,dublincore.description

<results>
<pages pages="3" pageNumber="1"/>
<document id="a3154f03-6baa-4d7d-8bac-579d52a8d304" icon="/icons/note.gif" title="ssl-uil2-service"/>
<document id="e2b26d9a-9140-44f1-ae23-4ad7866911c0" icon="/icons/note.gif" title="build"/>
<document id="bf7de6df-bca1-4d29-8e26-5019ced696fd" icon="/icons/note.gif" title="jboss-service"/>
<document id="439a11e8-642d-41f7-ae0f-4ef4d7303d79" icon="/icons/note.gif" title="postgres-jdbc2-service"/>
<document id="467745db-565d-4350-953f-b2fa03733406" icon="/icons/note.gif" title="oil-service"/>
<document id="44a2441e-e265-4fee-ad17-9ec24245cccf" icon="/icons/note.gif" title="jbossmq-state"/>
<document id="8d7e3077-a3be-4d6c-806c-aa97816821e2" icon="/icons/note.gif" title="oracle-jdbc2-service"/>
<document id="b431ad04-3439-441e-826b-48b5f0f0c1c8" icon="/icons/note.gif" title="as400-jdbc2-service"/>
<document id="e146c6b2-a315-4788-9bbe-5f1fc79c18ac" icon="/icons/note.gif" title="mssql-jdbc2-service"/>
<document id="b109a672-5ebd-4a01-8a86-79e2430c2f07" icon="/icons/note.gif" title="file-state-service"/>
</results> 

33.4. Nuxeo WebEngine Restlets

WebEngine is a new way to develop Restlets inside Nuxeo using the new specification JAX-RS.

Several restlets powered by WebEngine are already available, lets look at http://doc.nuxeo.org/xwiki/bin/view/Main/WebEngineTutorial to learn how to use them.