The Automation HTTP / REST Service
The Nuxeo Automation Server module provides a REST API to execute operations on a Nuxeo Server.
To use the Automation REST service you need to know the URL where the service is exposed, and the different formats used by the service to exchange information.
All the other URLs that appears in the content exchanged between the client and server are relative paths to the automation service URL.
Operations context and parameters as well as response objects (Documents) are formated as JSON objects. To transport blobs, HTTP multipart requests should be used to attach blob binary data along with the JSON objects describing the operation request.
The REST service is bound to the
By default all the chains and operations that are not UI related are accessible through REST. Anyway you can filter the set of exposed operations and chains or protect them using security rules. For more details on this see REST Operation Filters.
Example - Getting the Automation Service.
Let say the service is bound to http://localhost:8080/nuxeo/site/automation. Then to get the service description you should do:
You will get response a JSON document like:
You can see the automation service is returning the registry of operations and chains available on the server.
Each operation and chain signature is fully described to be able to do operation validation on client side, for instance.
Also some additional information that can be used in an UI is provided (operation label, full description , operation category etc.)
The "url" property of an operation (or operation chain) is the relative path to use to execute the operation.
For example if the service URL is http://localhost:8080/nuxeo/site/automation and the
Blob.Attach operation has the url
Blob.Attach then the full URL to that operation will be: http://localhost:8080/nuxeo/site/automation/Blob.Attach
paths property is used to specify various relative paths (relative to the automation service) of services exposed by the automation server.
In the above example you can see that the "login" service is using the relative path "login".
This service can be used to sign-in and check if the username/password is valid. To use this service you should do a POST to the login URL (e.g. http://localhost:8080/nuxeo/site/automation/login) using Basic Authentication. If authentication fails you will receive a 401 HTTP response. Otherwise the 200 code is returned.
The login service can be used to do (and check) a user login. Note that
WWW-Authenticate server response is not yet implemented so you need to send the basic authentication header in each call if you are not using cookies (in that case you only need once to authenticate - for example using the login service).
You do not need to be logged in to be able to get the automation service description
The operations registry (loaded doing a GET on the automation service URL) contains the entire information you need to execute operations.
To execute an operation you should build an operation request descriptor and post it on the operation URL.
When sending an operation request you must use the
application/json+nxrequest content type.
Also you need to authenticate (using Basic Authentication) your request since most of the operations are accessing the Nuxeo repository.
An operation request is a JSON document having the following format:
All these three request parameters are optional and depend on the executed operation.
If the operation has no input (a void operation) then the input parameter can be omitted.
If the operation has no parameters then 'params' can be omitted.
If the operation does not want to push some specific properties in the operation execution context then context can be omitted. In fact context parameters are useless for now but may be used in future.
The 'input' parameter is a string that acts as a reference to the real object to be used as the input.
There are 4 types of supported inputs: void, document, document list, blob, blob list.
To specify a "void" input (i.e. no input) you should omit the input parameter.
To specify a reference to a document you should use the document absolute path or document UID prefixed using the string "
doc:/default-domain/workspaces/myworkspace" or "
To specify a reference to a list of documents you should use a comma separated list of absolute document paths, or UID prefixed by the string "
docs:". Example: "
When using blobs (files) as input you cannot refer them using a string locator since the blob is usually a file on the client file system or raw binary data.
For example, let say you want to execute the
Blob.Attach operation that takes as input a blob and set it on the given document (the document is specified through 'params').
Because the file content you want to set is located on the client computer, you cannot use a string reference.
In that case you MUST use a multipart/related request that encapsulate as the root part your JSON request as an
application/json+nxrequest content and the blob binary content in a related part.
In case you want a list of blobs as input then you simply add one additional content part for each blob in the list.
The only limitation (in both blob and blob list case) is to put the request content part as the first part in the multipart document. The order of the blob parts will be preserved and blobs will be processed in the same order (the server assumes the request part is the first part of the multipart document - e.g. Content-Ids are not used by the server to identify the request part).
Example 1 - Invoking A Simple Operation
This operation will return the document content specified by the "
Example 2 - Invoking An Operation taking as input a Blob
Here is an example on invoking
Blob.Attach operation on a document given by its path ("
/default-domain/workspaces/myws/file" in our example).
In both examples you can see that the following
Accept header is used:
Accept: application/json+nxentity, /.
This header is important since is is specifying that the client accept as a response either a JSON encoded entity, either a blob that may have any type (in case of blob download).
application/json+nxentity is the first content type to help the server choose the format of the response when returning an encoded object.
Operation Execution Response
An Operation can have one of the following output types:
document- a repository document
documents- a list of documents
blob- a blob (binary content usually attached to a document)
blobs- a list of blobs
void- the operation has no output (output is void)
Apart from these possible outputs, the operation can abort due to an exception.
All these cases are represented using the following HTTP responses:
document-> a JSON object describing the document is returned. The used Content-Type is "application/json+nxentity"
documents-> a JSON object describing the document list is returned. The used Content-Type is "application/json+nxentity"
blob-> The blob raw content is returned. The used Content-Type will be the same as the blob mime-type.
blobs-> A Multipart/Mixed content is returned. Each part will be a blob from the list (order is preserved). Each part will use the right Content-Type as given by the blob mime-type.
void-> HTTP 204 is returned. No content and no Content-Type is returned.
exception-> A status code > 400 is returned and the content will be the server exception encoded as a JSON object.
The used Content-Type is "application/json+nxentity".
When an exception occurs, the server tries to return a meaningful status code. If no suitable status code is found, a generic 500 code (server error) is used.
You noticed that each time when return objects are encoded as JSON objects, the "application/json+nxentity" Content-Type will be used.
We also saw that only document, documents and exception objects are encoded as JSON.
Here we will discuss the JSON format used to encode these objects.
A JSON document entity contains the minimal required information about the document as top level entries.
These entries are always set on any document and are using the following keys:
uid- the document UID
path- the document path (in the repository)
type- the document type
state- the current life cycle state
title- the document title
lastModifed- the last modified timestamp
All the other document properties are contained within a "properties" map using the property XPath as the key for
the top level entries.
Complex properties are represented as embedded JSON objects and list properties as embedded JSON arrays.
Example of a JSON document entry:
The top level properties "
title" and "
lastModified" have the same value as the corresponding embedded properties "
dc:title" and "
The blob data, instead of containing the raw data, contains a relative URL (relative to automation service URL) that can be used
The documents JSON entity is a list of JSON document entities and have the entity type "
The documents in the list are containing only the required top level properties.
JSON exception entities have a "
exception" entity type. and contains information about the exception, including the server stack trace.
Special HTTP headers
There are four custom HTTP headers that you can use to have more control on how operations are executed:
Possible values: "true" or "false". If not specified the default is "false"
This header can be used to force the server to assume that the executed operation has no content to return (a void operation).
This can be very useful when dealing with blobs to avoid having the blob output sent back to the client.
For example, if you want to set a blob content on a document using "Blob.Attach" operation, after the operation execution, the blob you sent to the server is sent back to the client (because the operation is returning the original blob).
This behavior is useful when creating operation chains but when calling such an operation from remote it will to much network traffic than necessary.
To avoid this use the header:
This header can be used when you want to control the transaction duration. As an example, if you want to inject a large blob
in the repository, the default transaction timeout may be not enough. You can specify a 5 minutes timeout for the chain you're executing :
This header can be used whenever a Document will be returned by the server.
The header is forcing the server to fill up the returned document with data from schemas that matches the
X-NXDocumentProperties is a filter of schemas. If you don't use the header only the minimal required properties of the document are returned.
To have more properties in the returned document, you can specify a list of document schema names:
X-NXDocumentProperties: dublincore, file
or to have all the document content, you can use the '*' character as the filter value:
This header can be used to when you need to access a specific repository. The default value is 'default', as it's the default repository name in Nuxeo. This is handy if you have change the default name or if you have multiple repositories.
Document property types
Here you can find more details on the JSON document entity format.
- A document entity is using a string value for any scalar property value.
- Dates are encoded as W3C dates (in UTC timezone)
- Apart from strings, you may have null values for properties that are not set (but are defined by the schema), JSON objects (maps) for complex properties, and JSON arrays for array or list properties.
- blob data is encoded as a relative URL (relative to automation service URL) from where you can download the raw data of the blob (using a GET request on that URL)
Property values can be of one of these types:
long- encoded as a string representation of the number (in java:
double- encoded as a string representation of the number (in java:
date- encoded as a W3C format (UTC timezone preferred)
boolean- "true" or "false"
For null values the JSON null keyword is used.
Operation Request Parameters
Here you can find more details about the request format.
- Request input
As we seen a request may have as input:
- a document
- a list of documents
- a blob
- a list of blobs
To refer to a document you should use either the absolute path of the document (starting with '/' !) either the document UID.
input : "/" -> to refer to the repository root
input : "/default-domain/workspaces/ws" - to refer to the 'ws' workspace
input: "96bfb9cb-a13d-48a2-9bbd-9341fcf24801" - to refer to a document havin this UID.
To refer to a list of documents, you must use a comma separated list of document identifiers.
input: "/default-domain/workspaces/ws, 96bfb9cb-a13d-48a2-9bbd-9341fcf24801"
When using a blob as the input of an operation, you cannot use the "input" request property since the blob may contain binary data.
In that case you must use a Multipart/Related request as described above and put the blob raw data in the second body part of the request.
To use a list of blobs as the input, you should use the same method as for a single blob, and put each blob in the list in a separate body part.
Note that the order of the body parts is important: blobs will be processed in the same order that they appear in the Multipart document.
Also, when using Multipart/Related requests you must always put the JSON encoded request in the first body part.
- Request parameter types
The operation parameters specified inside the 'params' property of the request are all strings.
Operation parameters are typed, so on the server side the operation will know how to decode parameters in real Java classes.
The supported parameter types are: string, long (integer number), double (floating point number), date, properties, document, documents, EL expression, EL template.
Here are some rules on how to encode operation parameters:
- string: let it as is
- long: just use a string representation of the number (in java Long.toString())
- double: just use a string representation of the number (in java Double.toString())
- date: use W3C format (UTC timezone preferred)
- boolean: "true" or "false"
- document: use the document UID or the absolute document path
- documents: use a comma separated list of document references.
- EL expression: put the "expr:" string before your EL expression. (e.g. "expr: Document.path")
EL template: put the "expr:" string before your template. E.g.
Note that expressions also you specify relative paths (relative to the context document) using "
In fact all these encoding rules are the same as the one you can use when defining operation chains in Nuxeo XML extensions.
You can see operation chains as macro operations. These are chains of atomic operations that are registered on the server.
To extend the default operation set provided by Nuxeo, you can either write your own atomic operation, either define an operation chain through a Nuxeo XML extension.
When defining an operation chain on the server, it will become visible in the operation registry returned by the GET request o the automation service.
You must note that operation chains do not take parameters (only an input) because when defining such a chain, you also define all the parameters needed by each operation in the chain.
If you need parameterizable parameters (their value are computed at each execution), then use EL expressions as values.
Operation vs. Transactions
The server runs an operation or operation chain in a single transaction. A rollback is done if the operation execution caused an exception.
The transaction is committed when the operation (or operation chain) successfully terminated.
Operations can be executed in two different contexts: either in the context of a stateful repository session, either one session per operation.
By default operations are reusing the same session if your client supports cookies (even in Basic Authentication).
To enable stateless sessions, you need to modify some Nuxeo configuration. This will not be explained here (TODO: add link).
In stateless mode the session is closed at the end of the request.
Note that automation service is using Nuxeo WebEngine for HTTP request management.
Some operations are allowed to be executed only by some users or groups. This is defined on the server side through Nuxeo XML extensions.
See REST Operation Filters for more details.
Browser support will be improved by working on
multipart/form-data encoding support to execute operations.
A GWT client will be provided as an example.
A Java client is in progress. More details later.