expose Nuxeo Platform via http without losing our soul
Services to expose depends on deployment option
+workflowService +conversionService -relationService
Contribute custom Services
+myCustomBusinessService
Data Structures (users, docs ...) depends on configuration
{
common : {...},
dublincore : {...},
customSchema : {...},
...
}
"Pack" several services calls inside the same transaction
updateDoc + validateTask + generatePDF
Fetch all required information in one call
doc attributes + associated tasks + urls
efficiently manage streams
byte[] ==> evil
MultiPart ==> pain
manage authentication in an easy and pluggable way
be HTML/JavaScript friendly
new XMLHttpRequest()
expose a dynamic http API
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
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",
...
}
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, }, ... ] }
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",
...
}, { ...}, ...
]
}
Fetch all needed data in one call
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
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"
} } ] } ...
}
use RestContributor
to fetch additional info (Mixins)
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
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",
...
}, ... ] } }
}
@WebAdapter(name = BOAdapter.NAME,
type = "BOService", targetType = "Document")
@Produces({ "application/json+nxentity"})
public class BOAdapter extends DefaultAdapter {
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
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",
...
},
...}
Expose the API that matches your needs
doc => updateDoc
=(doc)=> validateTask
=(doc)=> generatePDF =(Blob)=>
Create new Operations via composition
via XML / via Drag&Drop
fetch resource => feed Operation or Chain
POST /nuxeo/api/v1/path/domain/workspaces/WS/note/@op/Blob.ToPDF
Cool, but what is the trade-off
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)
Java, Javascript, Python, Dart, Php, ObjectiveC ...
when is it ready ?
Cloud provisioning + API + online IDE