Well, Alfresco Community Edition 4.2.d has been out for a couple of weeks now and everyone I’ve talked to seems pretty excited about the new release. The new ribbon header in the Share user interface, the filmstrip view, and the table view for the document library seems to have gotten all of the attention (and it does look sharp) but my favorite new feature is actually behind-the-scenes: The Alfresco Public API has finally made its way from Alfresco in the cloud to on-premise.
What is the Alfresco Public API?
We’ve talked about it a lot over the last year, but it’s always been cloud-only, so you’re forgiven if you need a refresher. Basically, it means that we now have a documented, versioned, and backward compatible API that you can use to do things like:
- Get a list of sites a user can see
- Get some information about a site, including its members
- Add, update, or remove someone from a site
- Get information about a person, including their favorite sites and preferences
- Get the tags for a node, including updating a tag on a node
- Create, update, and delete comments on a node
- Like/unlike a node
- Do everything that CMIS can do
The Public API is comprised of CMIS for doing things like performing CRUD functions on documents and folders, querying for content, modifying ACLs, and creating relationships plus non-CMIS calls for things that CMIS doesn’t cover. When you run against Alfresco in the cloud you use OAuth2 for authentication. When you run against Alfresco on-premise, you use basic authentication.
I created some Java API examples for cloud a while ago. This week I spent some time on those examples to get them cleaned up a bit here and there and to have a really clear separation between what’s specific to running against Alfresco on-premise versus Alfresco in the cloud and what’s common to both. The result is a single set of code that runs against either one.
Here’s how the project is set up:
- com.alfresco.api.example.BasePublicAPIExample.java has several generic helper methods for things like creating documents and folders, commenting on a node, liking a node, etc. This code works unchanged regardless of whether you are targeting cloud or on-premise.
- com.alfresco.api.example.BaseCloudExample.java has a method for getting a CMIS session and a method for getting an HttpRequestFactory. The implementation of these methods is specific to Alfresco in the cloud because OAuth2 is used for authentication.
- com.alfresco.api.example.BaseOnPremExample.java also has methods for getting a CMIS session and a request factory, but that class uses basic authentication instead of OAuth2.
The remaining classes in com.alfresco.api.example are the actual examples. These would probably be better structured as unit tests but for now, they are just runnable Java classes. Currently there are only four:
- GetSitesExample.java simply fetches the short names of up to 10 sites the current user has access to.
- CmisRepositoryInfoExample.java is the simplest CMIS example you can write. It retrieves some basic information about the repository.
- CmisCreateDocumentExample.java creates a folder, creates a document, likes the folder, and comments on the document. This is a mix of CMIS and non-CMIS calls.
- CmisAspectExample.java imports some images, uses Apache Tika to extract some metadata from the binary image file, then uses the OpenCMIS Extension to store those metadata values in properties defined in aspects. The extension has to be used because CMIS 1.0 doesn’t support aspects.
Take a look at the readme.md file to see what changes you need to make to run these examples in your own environment.
New CMIS URLs in Alfresco Community Edition 4.2.d
One thing to notice is that starting with this release there are two new CMIS URLs. Which one you use depends on which version of CMIS you would like to leverage. If you want to use CMIS 1.0, the URL is:
If you would rather use CMIS 1.1, the URL is:
New with 4.2.d is the CMIS 1.1 browser binding. Currently Alfresco in the cloud only supports Atom Pub, but if you are only running against on-premise, you might decide that the browser binding, which uses JSON instead XML, is more performant. If you want to use the browser binding, the service URL is:
CMIS Repository ID and Object ID Changes
When using the new URLs, you’ll notice a couple of things right away. First, the repositoryId is coming back as “-default-” instead of the 32-byte string it used to return.
Second, the format of the object IDs has changed. The CMIS specification dictates that object IDs are supposed to be opaque. You shouldn’t build any logic on the content of a CMIS object ID. However, if you have built a client application that stores object IDs, you may want to pay particular attention to this when you test against the new version. The object IDs for the same object will be different than they were when using the old CMIS URLs.
You can see this in 4.2.d. If I use the old “/alfresco/cmisatom” URL, and I ask for the ID of the root folder, I’ll get:
But if I use either the new CMIS 1.0 URL or the new CMIS 1.1 URL and ask for the ID of the same root folder, I’ll get:
In order to minimize the impact of this change, you can issue a getObject call using either the old ID or the new ID and you’ll get the same object back. And if you ask for the object’s ID you’ll get it back in the same format that was used to retrieve it, as shown in this Python example:
Still Missing Some CMIS 1.1 Goodness
The browser binding is great but 4.2.d is still missing some of the CMIS 1.1 goodness. For example, CMIS 1.1 defines a new concept called “secondary types”. In Alfresco land we call those aspects. Unfortunately, 4.2.d does not yet appear to have full support for aspects. You can see what aspects a node has applied by inspecting the cmis:secondaryObjectTypeIds property, which is useful. But in my test, changing the value of that property did not affect the aspects on the object as I would expect if secondary type support was fully functional.
The Public API is new. There are still a lot of areas not covered by either CMIS or the rest of the Alfresco API. Hopefully those gaps will close over time. If you have an opinion on what should be the next area to be added to the Alfresco API, please comment here or mention it to your account rep.