Nuxeo Platform
&
API
Nuxeo Platform
-
not only a Content Repository
- provide tools to build Content Apps
- Configuration Studio
- API, SDK, Dev tools, Test tools
- Packaging and deployment tools
Build modern Web Apps
- Back to the client side
- Html 5 / JavaScript
- Mobile Apps
- Leverage Cloud promises
- ECM as a service
- Easy scaling
these 2 trends are driving the Roadmap for 5.9.x fastracks
API
is the main entry point
Nuxeo API challenges
expose Nuxeo Platform via http without losing our soul
Being dynamic
-
Services to expose depends on deployment option
+workflowService +conversionService -relationService
-
Contribute custom Services
+myCustomBusinessService
-
Data Structures (users, docs ...) depends on configuration
{ common : {...}, dublincore : {...}, customSchema : {...}, ... }
Being composable
-
"Pack" several services calls inside the same transaction
updateDoc + validateTask + generatePDF
-
Fetch all required information in one call
- aggregate all required info
doc attributes + associated tasks + urls
And also
-
efficiently manage streams
byte[] ==> evil MultiPart ==> pain
-
manage authentication in an easy and pluggable way
-
be HTML/JavaScript friendly
new XMLHttpRequest()
How we built the Automation API
expose a dynamic http API
Automation REST EndPoint
- Expose Nuxeo entities as REST resources
- Documents, Users, Workflows, Tasks ...
- Documents, Users, Workflows, Tasks ...
-
CRUD via GET, PUT, POST, DELETE
GET /nuxeo/api/v1/path/{path} HTTP/1.1
GET /nuxeo/api/v1/id/{uid} HTTP/1.1
GET /nuxeo/api/v1/user/{userName} HTTP/1.1
GET /nuxeo/api/v1/group/{groupId} HTTP/1.1
REST Endpoint : GET Document
GET /nuxeo/api/v1/path/default-domain/workspaces/WS/TestNote HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"entity-type": "document",
"repository": "default",
"uid": "6a3998e3-6890-45f5-9c19-b708814a9c1c",
"path": "/default-domain/workspaces/WS/TestNote",
"type": "Note",
"state": "project",
"versionLabel": "0.0",
"isCheckedOut": true,
"title": "TestNote",
"lastModified": "2014-01-20T13:11:29.64Z",
...
}
Automation RPC : Operations EndPoint
- Coarse grained API on top of Java API
- each services can contribute Operations
- each services can contribute Operations
- Expose endpoint for Operations
- GET to retrieve definition
- POST to execute
Operations EndPoint
GET /nuxeo/site/automation/Document.PageProvider HTTP/1.1
HTTP/1.1 200 OK Content-Type: application/json
id":"Document.PageProvider", "label":"PageProvider", "description":"Perform a query ...", "signature":[ "void", "documents" ], "params":[ { "name":"page", "type":"integer", "required":false },{ "name":"query", "type":"string", "required":false, }, ... ] }
Operations EndPoint
POST /nuxeo/site/automation/Document.PageProvider HTTP/1.1
Content-Type: application/json+nxrequest
{ "params" :
{ "query" : "select * from Note",
"page" : 0
}
}
HTTP/1.1 200 OK
Content-Type: application/json
{
"entity-type": "documents",
"pageIndex": 0,
"pageSize": 2,
"pageCount": 2,
"entries": [
{
"entity-type": "document",
"repository": "default",
"uid": "3f76a415-ad73-4522-9450-d12af25b7fb4",
...
}, { ...}, ...
]
}
Dynamic data structure
Fetch all needed data in one call
Control Marshaling
-
use header to control what schemas should be sent
X-NXDocumentProperties dublincore, common, file
fetch the data needed on the client side and nothing more
GET /nuxeo/api/v1/path/default-domain/workspaces/WS/TestNote HTTP/1.1
X-NXDocumentProperties note, files
Control Marshaling
GET /nuxeo/api/v1/path/default-domain/workspaces/WS/TestNote HTTP/1.1
X-NXDocumentProperties note, files
HTTP/1.1 200 OK
Content-Type: application/json
{ "entity-type": "document",
...
"properties": {
"note:mime_type": "text/x-web-markdown",
"note:note": "##Hello",
"files:files": [
{
"file": {
"name": "layout.png",
"mime-type": "image/png",
"length": "43627",
"data": "files/6a3998e3-6890-45f5-9c19-b708814a9c1c"
} } ] } ...
}
Fetch extra info
-
use
RestContributor
to fetch additional info (Mixins)- urls, breadcrumb info, comments, related documents ...
- urls, breadcrumb info, comments, related documents ...
-
use header to tell server what info is needed
X-NXContext-Category breadcrumb
GET /nuxeo/api/v1/path/default-domain/workspaces/WS/TestNote HTTP/1.1
X-NXContext-Category breadcrumb
Fetch REST contributions
GET /nuxeo/api/v1/path/default-domain/workspaces/WS/TestNote HTTP/1.1
X-NXContext-Category breadcrumb
HTTP/1.1 200 OK
Content-Type: application/json
{
"entity-type": "document",
...
"contextParameters": {
"breadcrumb": {
"entity-type": "documents",
"entries": [
{
"entity-type": "document",
"repository": "default",
"path": "/default-domain",
...
}, ... ] } }
}
Leverage adapter system
- contribute custom logic
@WebAdapter(name = BOAdapter.NAME,
type = "BOService", targetType = "Document")
@Produces({ "application/json+nxentity"})
public class BOAdapter extends DefaultAdapter {
- expose as business object with custom marshaling
GET /nuxeo/api/v1/path/domain/workspaces/WS/note/@audit HTTP/1.1
GET /nuxeo/api/v1/path/domain/workspaces/WS/note/@bo/MyBO HTTP/1.1
Fetch Audit records via adapter
GET /nuxeo/api/v1/path/domain/workspaces/WS/note/@audit HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"entity-type":"logEntries",
...
"entries":[
{
"entity-type":"logEntry",
"principalName":"tdelprat",
"docType":"Note",
"eventId":"documentCreated",
"repositoryId":"default",
"eventDate":"2014-01-12T16:58:55.294+01:00",
...
},
...}
Composable API
Expose the API that matches your needs
Automation Chains
- Operations have Input / Output and Arguments
- Operations can be chained on the service side
- one call , one transaction
doc => updateDoc
=(doc)=> validateTask
=(doc)=> generatePDF =(Blob)=>
Create new Operations via composition
Compose Chain
via XML / via Drag&Drop
Operations and resources
- Bridge Operations and Resource Endpoints
- "pipe Operation or Chain" on resource
fetch resource => feed Operation or Chain
POST /nuxeo/api/v1/path/domain/workspaces/WS/note/@op/Blob.ToPDF
Operations and Extensions
- Contribute new Operations via Extension Point
- Contribute new Adapters via Extension Point
- Compose Operations via Workflow
Dynamic and Composable API
Cool, but what is the trade-off
API is more powerful, but more complex
-
Data mapping needs to be dynamic
-
Calling dynamic endpoints is more complex than static API
endpoint.invoke("createDocument", {input: ... , params:...})
nuxeo.createDocument(path, name, type)
Solution :
- Provide introspection
- methods and data types
-
Provide client lib
- provides some data mapping
(document, blob)
- provides a high level simple API
(createDocument, addComment ...)
- does some checks
(validate method definition)
Java, Javascript, Python, Dart, Php, ObjectiveC ...
Mule Cloudhub example
- Leverage Java Lib service wrapper
- Plug Mule DataSense with Nuxeo Types introspection
- Mule fetches datatypes from Nuxeo
- Mule fetches datatypes from Nuxeo
-
Use invoke like pattern for dynamic Operations
- cannot dynamicaly build UI from Automation metadata
Dynamic data mapping
Roadmap & Next steps
when is it ready ?
Next steps : API
- API improvements are part of 5.9.x FastTrack releases
- REST EndPoints
- RestContributors and changes in marshaling
- SDK are in progress
- JavaScript
- Angular
- Dart
- iOs
- Android
-
Sample Apps and playground
Next steps : Cloud
-
nuxeo.io :
Nuxeo Platform as a Service
Cloud provisioning + API + online IDE
- Scaling
- Elastic Search integration
- NoSQL backend
Q&A ?
Nuxeo Platform & API
By Thierry Delprat
Nuxeo Platform & API
- 5,444