Views
Alfresco REST API Proposal
From alfrescowiki
Back to HTTP API.
NOTE:
This document presents ideas & thoughts for an Alfresco RESTful Web Services API for Content Management.
The content herein does not necessarily reflect current Alfresco product vision or development plan.
Proposal: Alfresco RESTful Web Services API
History:
27th March 07 - Initial thoughts & ideas
13th June 07 - Reformat and publish to Alfresco WIKI
This document presents ideas & thoughts for an Alfresco RESTful Web Services API for Content Management.
Objectives of this work are to:
- Explore the application of REST on Content Management
- Collect feedback on approach & desire
We're hosting this document on the Alfresco Wiki to encourage feedback and collaborative development from anyone who may have an interest in Content Management, RESTful approaches in general, or a combination of both. As such, this document is 'living' and changing for the foreseeable future as ideas stabilize, discussion takes place etc. Please note: the content herein does not necessarily reflect current Alfresco product vision or development plan.
Initially, a limited scope of services have been investigated. This is to minimise up-front work to get the ball rolling.
A simple test case has been used to kick-start the research; a federated search & update application which allows a single search across multiple content repositories, with view and update of items returned in search results. Alfresco Web Scripts will be used to enable rapid prototyping of ideas.
API Goals
The design goals of the HTTP API are:
- Simple as possible to understand and consume
- Minimum of client tooling
- Support remote access (batching / transactions)
- Support for multiple repository access
- Keep in-line with up-and-coming de-facto REST standards such as Atom, OpenID, OpenSearch
- Not brittle (i.e. upgrade service, add service etc)
- 100% Repository service coverage (eventually)
- Cross-repository links (eventually)
- Provide common interface to document mgt. and avm stores (for common functionality)
- Allow for API variants for client specific bindings (e.g. Browser client-side Javascript)
- Allow for distributed Repository components (future – i.e. add another content transformer at this network node)
Although the HTTP API may be used directly by clients, it is also envisioned that a client API will be provided for commonly used languages (e.g. Java/JCR, PHP, Javascript). The definition of the client API is deferred for now. However, it should be noted the same client API could be used for in-process Repository access too.
Constructs
The API is focused on a set of Alfresco “Resources�?. Resources include repository data such as folders & files, as well as services such as a Search Engine.
Each resource is given a URL – an identifier.
Resource representations have been modeled on Atom & Atom Publishing Protocol (APP). In most cases, collections are represented as an Atom feed, and items are represented as Atom entries. The extension mechanism of Atom is used to support Alfresco specific meta-data.
Resources support methods – the primary ones being GET, PUT, POST & DELETE. Not all methods are supported by all resources. After much deliberation, custom methods outside of the HTTP specification are introduced for some Alfresco capabilities. This is an area we definitely want feedback on.
Interaction patterns for creating, updating and deleting resources have also been borrowed from Atom Publishing Protocol.
Atom may not be the only representation. Via Web Scripts we could also provide alternative representations such as JSON (both on request and response). A transformation could be provided for Atom, JSON and RSS switching.
The constructs described are not unknown – see Google Data API.
Representations
Alfresco Resources are represented as one the following entity types (primarily in Atom):
Atom Feed
- application/atom+xml
- As specified in Atom syndication spec.
Atom Entry
- application/atom+xml;type=entry??
- As specified in Atom syndication spec.
Atom Service
- application/atomserv+xml
- As specified in Atom publishing spec plus a) repository meta data (e.g. Version). Note: Atom workspace => Alfresco store, Atom collections => Alfresco root container, locks, ...
OpenSearch Description
- application/opensearchdescription+xml
- As specified in OpenSearch spec.
OpenSearch Atom Feed
- application/atom+xml
- Atom syndication extensions as specified in Open Search spec.
Alfresco Saved Search
- application/opensearchdescription+xml
- OpenSearch Description plus a) query language b) query statement
Alfresco Item
- application/atom+xml;type=entry??
- Atom Entry plus a) type b) aspects c) property values d) permissions e) locks . Note: link rel=�?alternate�? or “enclosure�? is pointer to content, link rel=�?edit�? may apply to self or copy (if checked-out)
Alfresco Association
- application/atom+xml;type=entry??
- Atom Entry plus a) assoc type? b) from or to?
Alfresco Lock
- application/atom+xml;type=entry??
- Atom Entry plus a) lock type (read, write, checkout) b) owner c) include children d) time to expire (optional) e) item (rel=�?locked item�?)
Alfresco Checkin Note
- application/atom+xml;type=entry??
- Atom Entry plus a) keep locked b) checkin properties c) lock??
Alternative Representation: JSON
TODO: Mapping between Atom and JSON?
Alternative Representation: HTML
This is an interesting direction. Essentially, this provides a “visual�? api. The URIs remain the same, but the results are rendered in a form for human consumption. Navigation is a case of issuing further API URIs – links within HTML. Forms could be provided for creates and updates. Very useful for learning, testing and debugging the API. Could also become an generic Repository Browser, but with updates, and for all Repository services.
Custom HTTP Methods
The following custom HTTP methods are provided for performing “advanced�? Resource operations. Actually, WebDAV has similar. Alternative approaches are listed below.
Why?
- Apply method directly to Resource (just require URL) – no need to establish correct “service�? url which might be difficult in distributed environment
- Apply method to many different kinds of Resource including collections e.g. Search results
For those clients or environments which lock down HTTP methods, it is envisioned that they can be tunneled through POST by adding a header such as X-Method-Override. See Web Script Method Tunneling.
ITEMLOCK
- Representation: Alfresco Lock
- Status: 201 Content location: Alfresco Lock
ITEMUNLOCK
- Representation: Alfresco Lock??
- 200??
ITEMCHECKOUT
- Representation: Alfresco Lock
- Status: 201 Content location: Alfresco Lock
ITEMCHECKIN
- Representation: Alfresco Checkin Note
- Status: 200 Alfresco Lock
SETPROP (update individual properties)
TBD
Resources
The API exposes the following Resources. An example URI is given to assist visualization of the API, although the syntax is not important (only for easing human understanding / consumption).
Some Resources may be provisioned by both Document Mgt. & WCM stores. The representation of such Resources is consistent across both. Where possible, the supported methods are also consistent, however, some may not be supported, but that should be kept to a minimum. The example URIs are driven by a Document Mgt store. Alternative syntax may be used for WCM.
Repository
- GET /repository => Atom Service
- Lists repository meta-data and available workspaces (i.e. Stores)
Search Engine Registry
- GET /search/engines => Atom Feed (of Atom Entry)
- List registered search engines
Keyword Search Description
- GET /search/keyword/description => OpenSearch Description
- Get Keyword search description
SQL Search Description
- GET /search/sql/description => OpenSearch Description
- Get SQL search engine description
Alfresco Lucene Search Description
- GET /search/lucene/description => OpenSearch Description
- Get lucene search engine description
Keyword Search Results
- GET /search/keyword => OpenSearch Atom Feed
- Perform “google�? like search (Repository wide)
- ITEMLOCK /search/keyword <= Alfresco Lock
- Lock all items in search results
- ITEMUNLOCK /search/keyword <= Unlock Item
- Unlock all items in search results
SQL Search Results
- GET /search/sql => OpenSearch Atom Feed
- Perform SQL search (Repository wide)
- ITEMLOCK /search/sql => Alfresco Lock
- Lock all items search results
- ITEMUNLOCK /search/sql => Alfresco Lock
- Unlock all items in search results
Alfresco Lucene Search Results
- GET /search/lucene => OpenSearch Atom Feed
- Perform lucene search (Repository wide)
- ITEMLOCK /search/lucene <= Alfresco Lock
- Lock all items search results
- ITEMUNLOCK /search/lucene <= Alfresco Lock
- Unlock all items in search results
Saved Searches Registry
- GET /search/saved => Atom Feed (of Alfresco Saved Search)
- List saved searches
- POST /search/saved => Alfresco Saved Search
- Create saved search
Alfresco Saved Search
- GET /search/saved/{name}/description => Alfresco Saved Search
- Get saved search
- PUT /search/saved/{name}/description <= Alfresco Saved Search
- Update saved search
- SETPROP /search/saved/{name}/description <= TBD
- Partial Update
- DELETE /search/saved/{name}/description
- Remove saved search
Item (node/container)
- GET /path/{store}/{storeid}/{path}, /node/{noderef} => Alfresco Item
- Get item – meta-data
- PUT /path/{store}/{storeid}/{path}, /node/{noderef} <= Alfresco Item
- Update item – meta-data
- SETPROP /path/{store}/{storeid}/{path}, /node/{noderef} <= TBD
- Partial Update item – meta-data
- DELETE /path/{store}/{storeid}/{path}, /node/{noderef}
- Delete item
- ITEMLOCK /path/{store}/{storeid}/{path}, /node/{noderef} => Alfresco Lock
- Lock Item
- ITEMUNLOCK /path/{store}/{storeid}/{path}, /node/{noderef} <= Alfresco Lock
- Unlock Item
- ITEMCHECKOUT /path/{store}/{storeid}/{path}, /node/{noderef} => Alfresco Lock
- Checkout Item
- ITEMCHECKIN /path/{store}/{storeid}/{path}, /node/{noderef} => Alfresco Checkin Note
- Checkin Item
Item Children
- GET /path/children/{store}/{storeid}/{path}, /node/children/{noderef} => Atom Feed (of Alfresco Item)
- Get the children of a container (folder etc)
Item Associations
- GET /path/links/{store}/{storeid}/{path}, /node/links/{noderef} => Atom Feed (of Alfresco Association)
- Get assocs to / from item
Item Associations of Type
- GET /path/links;{assocType}/{store}/{storeid}/{path}, /node/links;{assocType}/{noderef} => Atom Feed (of Alfresco Association)
- Get assocs of type to / from item
- POST /path/links;{assocType}/{store}/{storeid}/{path}, /node/links;{assocType}/{noderef} <= Alfresco Association
- Create assoc of type
Item Association
- GET /assoc/{associd} => Alfresco Association
- Get association
- PUT /assoc/{associd} <= Alfresco Association
- Replace assocation
- SETPROP /assoc/{associd} <= Alfresco Association
- Partial Update of association (inc. order)
- DELETE /assoc/{associd}
- Delete assoc
Content
- GET /path/content{;propname}/{store}/{storeid}/{path}, /node/content{;propname}/{noderef} => Content specific
- Retrieve content
- PUT /path/content{;propname}/{store}/{storeid}/{path}, /node/content{;propname}/{noderef} <= Content specific
- Push content
- DELETE /path/content{;propname}/{store}/{storeid}/{path}, /node/content{;propname}/{noderef}
- Remove content
All Locks
- GET /locks[?type={locktype}] => Atom Feed (of Alfresco Lock)
- Retrieve all locks in Repository
All Locks for User
- GET /user/{userid}/locks[?type={locktype}] => Atom Feed (of Alfresco Lock)
- Retrieve locks owned by user
All Locks for Item
- GET /path/locks/{store}/{storeid}/{path}[?type={locktype}], /node/locks/{noderef}[?type={locktype}] => Atom Feed (of Alfresco Lock)
- Retrieve all locks for item (& child items)
Lock
- GET /lock/{lockid} => Alfresco Lock
- Retrieve lock
- DELETE /lock/{lockid}
- Remove lock (or cancel checkout)
Supporting Services
Transactions
- Idea – transactions are enabled by exposing them as a resource. Actions are added to the transaction by POSTing to the transaction resource. Essentially, each action is a request i.e. Method + URL + Entity; the transaction is the collection of actions. The transaction is committed by setting the “status�? of the transaction resource. The transaction is aborted by deleting the transaction resource. Something akin to HTTP WRAPPED method once defined in HTTP specification.
- Use pattern described in RESTful Web Services book
Authentication
- Alfresco Web Client
- NTLM SSO
- HTTP Basic Authentication
- WSSE applied to HTTP
- OpenID
The main issue here is how to support multiple repository access from one client.
Appendix A: Alternatives to Custom HTTP Methods
Manager / Service Resources
/checkouts
POST checkout
DELETE GET /checkout/{coid}
POST checkin
/locks
POST lock
DELETE GET /lock/{loid}