gavincornwell

v1 REST API - Part 5 - Versioning & Locking

Blog Post created by gavincornwell Employee on Nov 11, 2016

In the last post we looked at how to retrieve, update and delete nodes, this time we're going to concentrate on versioning.

 

 

As always there is a Postman collection to accompany this post. To import the collection click on the "Run in Postman" button below.

 

Let's start by creating an empty file like we did in the last post by POSTing the following body to http://localhost:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/-my-/children (1st request in the Postman collection):

 

{
  "name": "version.txt",
  "nodeType": "cm:content"
}

 

If you examine the response below you'll notice there's no mention of versioning at all, that's because empty files are created without versioning enabled.

Note: If you want to create content with versioning enabled by default use multipart/form-data instead of JSON, refer back to part 3 or see http://localhost:8080/api-explorer/#!/nodes/addNode for details.

{
  "entry": {
    "aspectNames": [
      "cm:auditable"
    ],
    "createdAt": "2016-11-10T21:35:04.389+0000",
    "isFolder": false,
    "isFile": true,
    "createdByUser": {
      "id": "test",
      "displayName": "Test Test"
    },
    "modifiedAt": "2016-11-10T21:35:04.389+0000",
    "modifiedByUser": {
      "id": "test",
      "displayName": "Test Test"
    },
    "name": "version.txt",
    "id": "fa100bae-9903-44e4-9e19-5a8523be7422",
    "nodeType": "cm:content",
    "content": {
      "mimeType": "text\/plain",
      "mimeTypeName": "Plain Text",
      "sizeInBytes": 0,
      "encoding": "UTF-8"
    },
    "parentId": "bd8f1283-3e84-4585-aafc-12da26db760f"
  }
}

 

Now let's update the content like we did in the last post but this time also provide the majorVersion and comment query parameters.

 

To do this, PUT the body below with a Content-Type of text/plain to http://localhost:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/fa100bae-9903-44e4-9e19-5a8523be7422/content?majorVersion=true&comment=First version (2nd request in Postman collection):

Note: You'll obviously need to replace fa100bae-9903-44e4-9e19-5a8523be7422 with the id from your response throughout this post.

This is the initial content for the file.

 

This should return a response similar to the one below:

 

{
  "entry": {
    "isFile": true,
    "createdByUser": {
      "id": "test",
      "displayName": "Test Test"
    },
    "modifiedAt": "2016-11-10T21:48:28.014+0000",
    "nodeType": "cm:content",
    "content": {
      "mimeType": "text\/plain",
      "mimeTypeName": "Plain Text",
      "sizeInBytes": 41,
      "encoding": "ISO-8859-1"
    },
    "parentId": "bd8f1283-3e84-4585-aafc-12da26db760f",
    "aspectNames": [
      "cm:versionable",
      "cm:titled",
      "cm:auditable",
      "cm:author"
    ],
    "createdAt": "2016-11-10T21:35:04.389+0000",
    "isFolder": false,
    "modifiedByUser": {
      "id": "test",
      "displayName": "Test Test"
    },
    "name": "version.txt",
    "id": "fa100bae-9903-44e4-9e19-5a8523be7422",
    "properties": {
      "cm:versionLabel": "1.0",
      "cm:versionType": "MAJOR"
    }
  }
}

 

You can see from the response that the cm:versionable aspect has been applied (line 18) and two version properties have been set (lines 32 and 33), cm:versionLabel and cm:versionType.

 

Now versioning is enabled we can retrieve the version history for the file by using the URL http://localhost:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/fa100bae-9903-44e4-9e19-5a8523be7422/versions (3rd request in the Postman collection):

 

{
  "list": {
    "pagination": {
      "count": 1,
      "hasMoreItems": false,
      "totalItems": 1,
      "skipCount": 0,
      "maxItems": 100
    },
    "entries": [
      {
        "entry": {
          "isFolder": false,
          "isFile": true,
          "modifiedAt": "2016-11-10T21:48:28.014+0000",
          "modifiedByUser": {
            "id": "test",
            "displayName": "Test Test"
          },
          "name": "version.txt",
          "versionComment": "First version",
          "id": "1.0",
          "nodeType": "cm:content",
          "content": {
            "mimeType": "text\/plain",
            "mimeTypeName": "Plain Text",
            "sizeInBytes": 41,
            "encoding": "ISO-8859-1"
          }
        }
      }
    ]
  }
}

 

We can see from the response above that there's only one version right now so let's create another one. This time though we'll create a minor version by using http://localhost:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/fa100bae-9903-44e4-9e19-5a8523be7422/content?majorVersion=false&comment=Second version (4th request in Postman collection) and setting the content to:

 

This is the second version of the content, v1.1.

Now retrieve the version history again and you should see a response like the one shown below. This is also where you'll see the comments we specified (lines 21 and 42) when creating new versions.

 

{
  "list": {
    "pagination": {
      "count": 2,
      "hasMoreItems": false,
      "totalItems": 2,
      "skipCount": 0,
      "maxItems": 100
    },
    "entries": [
      {
        "entry": {
          "isFolder": false,
          "isFile": true,
          "modifiedAt": "2016-11-10T22:03:11.658+0000",
          "modifiedByUser": {
            "id": "test",
            "displayName": "Test Test"
          },
          "name": "version.txt",
          "versionComment": "Second version",
          "id": "1.1",
          "nodeType": "cm:content",
          "content": {
            "mimeType": "text\/plain",
            "mimeTypeName": "Plain Text",
            "sizeInBytes": 48,
            "encoding": "ISO-8859-1"
          }
        }
      },
      {
        "entry": {
          "isFolder": false,
          "isFile": true,
          "modifiedAt": "2016-11-10T21:48:28.014+0000",
          "modifiedByUser": {
            "id": "test",
            "displayName": "Test Test"
          },
          "name": "version.txt",
          "versionComment": "First version",
          "id": "1.0",
          "nodeType": "cm:content",
          "content": {
            "mimeType": "text\/plain",
            "mimeTypeName": "Plain Text",
            "sizeInBytes": 41,
            "encoding": "ISO-8859-1"
          }
        }
      }
    ]
  }
}

 

As you'd expect, if we retrieve the content for the node using http://localhost:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/fa100bae-9903-44e4-9e19-5a8523be7422/content (5th request in Postman collection) we get:

 

This is the second version of the content, v1.1.


We can still get the content of the initial version though, to do this we have to use http://localhost:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/fa100bae-9903-44e4-9e19-5a8523be7422/versions/1.0/content (6th request in the Postman collection), this gives us our original content:

 

This is the initial content for the file.


Imagine we change our mind and decide we want to revert to a previous version. To revert to version 1.0 we have to POST the following body to http://localhost:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/fa100bae-9903-44e4-9e19-5a8523be7422/versions/1.0/revert (7th request in the Postman collection):

 

{
  "majorVersion": true,
  "comment": "Reverted to original"
}


We are able to specify whether the reverted version will create a new minor or major version and again provide a comment describing the reason for the additional version.

 

If you get the content now it should be back to what it was when we originally created the file and if you get the version history you'll see we now have an extra version, a 2.0.

 

Now, what if you wanted to make some changes to a file and not let anyone else make changes until you've finished?

 

For this situation we can lock the file by POSTing an empty JSON object (see below) to http://localhost:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/fa100bae-9903-44e4-9e19-5a8523be7422/lock (8th request in the Postman collection).

 

{}


This results in the response below, which shows the node has been locked (lines 31, 32 and 38).

 

{
  "entry": {
    "isFile": true,
    "createdByUser": {
      "id": "test",
      "displayName": "Test Test"
    },
    "modifiedAt": "2016-11-10T22:07:41.857+0000",
    "nodeType": "cm:content",
    "content": {
      "mimeType": "text\/plain",
      "mimeTypeName": "Plain Text",
      "sizeInBytes": 41,
      "encoding": "ISO-8859-1"
    },
    "parentId": "bd8f1283-3e84-4585-aafc-12da26db760f",
    "aspectNames": [
      "cm:versionable",
      "cm:lockable",
      "cm:auditable"
    ],
    "createdAt": "2016-11-10T21:35:04.389+0000",
    "isFolder": false,
    "modifiedByUser": {
      "id": "test",
      "displayName": "Test Test"
    },
    "name": "version.txt",
    "id": "fa100bae-9903-44e4-9e19-5a8523be7422",
    "properties": {
      "cm:lockType": "WRITE_LOCK",
      "cm:lockOwner": {
        "id": "test",
        "displayName": "Test Test"
      },
      "cm:versionType": "MAJOR",
      "cm:versionLabel": "2.0",
      "cm:lockLifetime": "PERSISTENT"
    }
  }
}

 

There are a few options when using lock, see http://localhost:8080/api-explorer/#!/nodes/lockNode for more details. It's also possible to include an isLocked property when retrieving a node or a children listing so that your client does not need to parse these properties.

 

As the owner of the lock we can make changes to the file including the content, use the same update content URL we used earlier (2nd or 4th request in the Postman collection) to update the content and generate a new version.

 

However, if you try the same request as another user you'll get a 409 Conflict error response.

 

To unlock the file once you're done with your changes you can POST an empty JSON object (see below) to http://localhost:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/fa100bae-9903-44e4-9e19-5a8523be7422/unlock (9th request in the Postman collection)

 

{}


We've almost covered all the functionality provided by the /nodes API, next time we'll look at the last remaining area, associations.

Outcomes