cancel
Showing results for 
Search instead for 
Did you mean: 
resplin
Elite Collaborator
Elite Collaborator

Obsolete Pages{{Obsolete}}

The official documentation is at: http://docs.alfresco.com

Developing
This page attempts to gather together design guidelines for the Alfresco REST API.  As time passes this page should evolve towards a standard for Alfresco REST scripts.   The items on this page have been reviewed at least once, the discussion page has content awaiting review.

Other Coding Standards are here.


Web Script Definition


Requirements for the alfresco public API


Methods that are part of the public API are identified by the web script lifecycle value of 'public_api' and are supported and will be maintained between different versions of Alfresco.   A greater level of care needs to be applied for public api scripts.

Before a method can be marked as part of the public API.


  • Method must conform to these published guidelines.
  • Method must have jUnit tests (otherwise we can't know that the interface is stable).
  • Documentation must be present and reviewed. 
  • Method must be strategic, for example intentionally temporary methods or expermimental code are not part of the public api.

Changes to a public script need to be reviewed and approved by the 'owner' of the scripts.   Changes to existing scripts will be discouraged.

Data should be returned in both JSON and ATOM formats.


HTTP Status Codes


The following HTTP status codes should be used by the Alfresco REST API.   (This is not a complete list, extra codes can be returned)


200 OK : Command completed successfully.
201 CREATED : Object created
202 ACCEPTED : Object will be created soon
400 Bad Request : Invalid URL, missing argument etc.
404 Not found : object does not exist.
500 Internal Server Error : an error has occurred.

Use of PUT


The PUT command is used to update an existing object in Alfresco.

A return status of STATUS_OK indicates that the object has been updated successfully.


Partial Updates


Partial updates are ambiguous (what does a missing attribute mean?) so until a full solution is agreed Alfresco api's should avoid doing partial updates.


Concurrent modifications


Update methods should consider the need to detect concurrent modifications.

Mrogers 16:17, 10 November 2008 (UTC) 1st review meeting - update should detect concurrent modifications,  take CMIS ETag implementation as a guideline. 


Modification of large graphs


See discussion section for one possible approach. - no standard as yet.


Use of GET


The get method retrieves a read-only representation of an object from a web server.    If the object does not exist error 404 (NOT_FOUND) is returned.   The action of a get method should be compatible with caching.

Public Service API Get methods should be able to return JSON and ATOM data and optionally other formats such as 'text' and 'xml'.

The return format should be determined by either a 'format' argument or by an 'Accept' HTTP Request Header value.

The HTTP response header should contain an ETag to assist with caching and concurrent modification.

Get methods should not be used to trigger an action or side-effect (although some ad-hoc state change for example a usage counter is O.K.)


Return Status STATUS_OK(200) : entity corresponding to the requested resource is sent in the response;

Use of DELETE


The delete HTTP command is used to delete an existing object.

We should probably (there may be exceptions) detect whether the object already exists prior to deleting it. 

If the object does not exist throw a 404 (NOT_FOUND)


Use of POST


The post HTTP method is used to create a new object or trigger an action or side-effect.    

If some dependency of the object does not exist then a 404 (NOT_FOUND) should be returned.   However there may be occasional cases where this is not appropriate.


return status


The following status codes will commonly be used by the alfresco scripts responding to POST.    The actual values returned will need to be documented in the script definition file.


Status 400 (BAD_REQUEST) : bad request, missing mandatory parameter etc;

Status 404 (NOT_FOUND) : a dependency of the object is not found;

Status 200 STATUS_OK :  an entity describing or containing the result of the action;

Status 201 STATUS_CREATED :

The request has been fulfilled and resulted in a new resource being created. The newly created resource can be referenced by the URI(s) returned in the entity of the response, with the most specific URI for the resource given by a Location header field. The response SHOULD include an entity containing a list of resource characteristics and location(s) from which the user or user agent can choose the one most appropriate. The entity format is specified by the media type given in the Content-Type header field. The origin server MUST create the resource before returning the 201 status code. If the action cannot be carried out immediately, the server SHOULD respond with 202 (Accepted) response instead

A 201 response MAY contain an ETag response header field indicating the current value of the entity tag for the requested variant just created, see section 14.19.;


Alfresco JSON data objects


Standard JSON Response Format


All JSON based web data web scripts should return their data in the following structure:



{
   'data':  <result JSON data, either a JSON object or array>,
   'paging': <meta-data about the paged collection>,
}

Where:


  • data - the data resulting from the web script call as specified in the API design documentation.  This can either be a JSON object or JSON array
  • paging - optional - if the data is a paged collection then this will contain the related paging data.

We may also gain further top level attributes as requirements become clear, here are some candidates


  • status - optional - a place to put extended status information, or metadata about the result set ??
  • actions - optional - links to the available actions related to the data.

case of attributes


camel case names. e.g. displayName


property names


Can we standardise on property names for json objects?    Mrogers 17:32, 10 November 2008 (UTC) Probably.

Mrogers 17:32, 10 November 2008 (UTC) Review action here - standardise the idea of 'mini sections' here.


id : the unique id for an object.
title : the property named title is the display name of the object.    Which can be internationalised.
url : is the url of the associated object.   There should be a url for all objects.

arrays or maps


Early review feedback of the site service was that it can be more convenient to return a map of data rather than an array of data.  

This allows java script of the form wombats.bruce.title rather than having to loop through an array of JSON objects.

--Rwetherall 11:28, 10 November 2008 (UTC) if the name in the map is a QName (eg: the type name) the full QName URL will contain characters that mean dot notation to the item can not work.  Indeed even using the short name (eg cm:content) may not work since bobbins.list.cm:content may not work since : is an invalid char in a variable name (in PHP at least!).  In the case of PHP we have used cm_content style, also in the dictionary URL's we use cm_content style short names ... comments?

-- Mrogers 11:26, 11 November 2008 (UTC) We need to be careful what we use as our primary keys (or at least the keys by which we expose on the REST API to uniquely identify objects).  The keys need to be suitable for URL encoding (so no spaces or japaneese characters) and were also seeing that they need to be compatible with JavaScript so characters like '.+-=?/!*' will be problematic.    As long as we are carefully choose our keys to be alphanumeric for the REST API then we should be O.K.    For example we could consider using GUIDs rather than 'title' as a key.   If we are to use title then we will either have to restrict the characters or replace any dodgy characters.  

Replace ':' with '_' for URLS.


true / false values


How to represent boolean values in JSON?

At the moment we have confusion between boolean and string values.    Use boolean type, don't use strings with 'true' or 'false'.

Rwetherall 11:29, 10 November 2008 (UTC) I've been using boolean (eg: { 'name' : false } )

Mrogers 12:40, 20 November 2008 (UTC) I'm not sure if this is the best way to do this,  I've had problems. But here is a working freemarker example which exposes a Java based boolean value over JSON.



   'isTemplate': ${webproject.template?string('true', 'false')},

Representation of dates in JSON


For Alfresco Public API methods Dates should be strings in iso8601 format.

Here is an example, the createdOn field is a date in JSON.



{
   'data':
   {
      'sandboxref': 'buffy',
      'createdOn': '2008-11-12T13:51:41.156Z',
      'url': '\/alfresco\/service\/api\/wcm\/webprojects\/buffy\/sandboxes\/buffy'
   }
}

Alfresco provides a utility class to transform java.util.Dates to and from iso8601 format, ISO8601DateFormat.  

There are also utility methods to convert java script dates to and from iso8601.

We may in the future add other data formats, in particular an 'exploded' date format.

They would be identified by an object containing a property matching the format i.e. 'iso8601', an example is shown below.



{
   'data':
   {
      'sandboxref': 'buffy',
      'createdOn':
      {
         'iso8601': '2008-11-12T13:51:41.156Z'
      },
      'url': '\/alfresco\/service\/api\/wcm\/webprojects\/buffy\/sandboxes\/buffy'
   }
}

Discussion about JSON Date formats


Data Paging


It is often desirable to page results from data requests to ensure that the volume of data returned to the client is manageable. The following describes the parameters and resulting data structure that should be used when adding paging functionality to a web script.


Data Paging Parameters


?size={pagesize}&pos={pageposition}

  • The pagesize specifies the number of items to be returned on each page.
  • The pageposition indicates which page we are currently requesting data for.
  • If the pageposition parameter is not specified it is assumed we are on the first page.

Data Paging Result


Included in the data page result is the following:


  • URL to the first page in the data set
  • URL to the previous page in the data set
  • URL to the next page in the data set
  • URL to the last page in the data set



Proposed response json:



'paging':
{
   'firstPage': 'url',
   'previousPage': 'url',
   'nextPage': 'url',
   'lastPage': 'url',
   'pagePos': 1,
   'pageSize': 10,
   'total': 14,
}

Comments:


  • The YUI paginator which might be used at some point uses other variables: recordOffset, totalRecords, rowsPerPage. Shouldn't we rather specify the first element of the range to retrieve than the absolute page number?
  • 'total' specifies the total number of elements in the result set. If we go for pagePos it might make more sense to return 'pageCount' instead
  • Mrogers 13:36, 7 November 2008 (UTC) The existing atom pager (paging.lib.atom.ftl) has attributes for the 4 urls called first, last, prev, next.  It doesn't have the numeric propeties.   Does it matter that this is inconsistent?

URL Arguments


Case of arguments


Arguments should be cammel case - use java naming conventions.  e.g nameFilter.


Abbreviations of arguments


Use short names for arguments rather than unreadable short names or very long winded names.   Except for the case where the length of a URL is an issue.

For example,


site?nf={nameFilter} : too short - can't read it
site?nameFilterUsedBySiteService={nameFilter} : too long  
site?nameFilter={nameFilter} : just right !

Standard atribute names


size : maximum number of records to return in a result set
pos : starting position in a result set
format : the format of data to return.   Important values are 'json', 'atom', 'text', 'html', 'xml'.

URI considerations


Although the URI is only of secondary importance to the resource being affected by the web scripts the consistency of URIs helps in being able to understand and use the API.


plural objects


When constructing URLs that contain parent/child relationships use a plural identifier for the association.

For example these are good URLs to use.

/api/wombats returns a collection of wombats.

/api/wombats/wombatRef identifies a single wombat.

/api/wombats/sheila/children identifies the collection of the children of the wombat called sheila.

/api/wombats/sheila/children/bruce identifies the wombat bruce, child of sheila

Please note that there are existing URIs, notably site and node that do not follow this pattern.     For consistency we should add sites and nodes.


To be agreed


Alfresco_REST_Design_Guidelines