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.1GET /nuxeo/api/v1/id/{uid} HTTP/1.1GET /nuxeo/api/v1/user/{userName} HTTP/1.1GET /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, filefetch 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, filesHTTP/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
RestContributorto 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 breadcrumbHTTP/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,647