In the we looked at how to navigate the repository, this time we're going to create some files and folders.
As before all of the endpoints we'll cover in this blog post have been provided in a Postman collection and can be imported by clicking the "Run in Postman" button below.
Let's start with creating a folder in our home folder. We use the same URL as we did for navigating the repository but this time we'll POST to it and use the -my- alias.
To create a folder named "My Folder" POST the body below using a Content-Type of application/json to http://localhost:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/-my-/children
{
"name":"My Folder",
"nodeType":"cm:folder"
}
This results in a response representing the newly created folder as shown below:
{
"entry": {
"aspectNames": [
"cm:auditable"
],
"createdAt": "2016-10-17T18:30:28.870+0000",
"isFolder": true,
"isFile": false,
"createdByUser": {
"id": "test",
"displayName": "Test Test"
},
"modifiedAt": "2016-10-17T18:30:28.870+0000",
"modifiedByUser": {
"id": "test",
"displayName": "Test Test"
},
"name": "My Folder",
"id": "de8f6834-1d5a-4137-ab1f-67e6978f1aa8",
"nodeType": "cm:folder",
"parentId": "bd8f1283-3e84-4585-aafc-12da26db760f"
}
}
You may have noticed that slightly more information about the node (aspectNames and properties) is returned by default but even here we are still using a "performance first" principle. The include parameter can also be used with create, see http://localhost:8080/api-explorer/#!/nodes/addNode for the list of extra information you can request.
Let's now create an empty file within our home folder. Once again we'll POST to http://localhost:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/-my-/children but this time we'll send the following body:
{
"name": "my-file.txt",
"nodeType": "cm:content"
}
This results in a response representing the newly created document as shown below:
{
"entry": {
"aspectNames": [
"cm:auditable"
],
"createdAt": "2016-10-17T18:58:38.717+0000",
"isFolder": false,
"isFile": true,
"createdByUser": {
"id": "test",
"displayName": "Test Test"
},
"modifiedAt": "2016-10-17T18:58:38.717+0000",
"modifiedByUser": {
"id": "test",
"displayName": "Test Test"
},
"name": "my-file.txt",
"id": "e88e9b0f-7975-4398-beb4-db593b0b7aee",
"nodeType": "cm:content",
"content": {
"mimeType": "text/plain",
"mimeTypeName": "Plain Text",
"sizeInBytes": 0,
"encoding": "UTF-8"
},
"parentId": "bd8f1283-3e84-4585-aafc-12da26db760f"
}
}
As well as accepting JSON the same endpoint also accepts multipart/form-data, allowing us to upload content from a standard HTML form or from the command line using curl.
Presuming there is a file named test.txt in the current directory try the following command:
curl -X POST -H "Authorization: Basic dGVzdDp0ZXN0" -H "Content-Type: multipart/form-data; boundary=----FormBoundary7MA4YWxkTrZu0gW" -F "filedata=@test.txt" "http://localhost:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/-my-/children"
Alternatively, the 3rd request in the Postman collection can be used after selecting a file in the "Body" tab as shown in the screenshot below.
If you hadn't already noticed, one of the benefits of the API Explorer is that it allows you to "Try it out!" on all documented APIs. Unfortunately the OpenAPI specification does not currently allow multiple content types to be documented for the same endpoint. For POST /nodes/-my-/children we made the decision to focus the API Explorer on JSON to allow the creation of folders and files. We have however fully documented what is possible via multipart/form-data, we'll discuss a few of those options next.
To specify the name of the file that gets created you can use a form field called name as shown in the screenshot below. You can try this for yourself via the 4th request in the Postman collection.
When uploading content it's quite common for a file with the same name to exist, this will generate an error by default, to avoid the error the autoRename form field can be used as shown below. You can try this for yourself via the 5th request in the Postman collection. If a file name clash is detected a suffix will be added to the file name, for example my-file.txt will become my-file-1.txt.
The same thing can be achieved whilst creating folders and empty files via the same named query parameter, for example: http://localhost:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/-my-/children?autoRena...
In some scenarios the path of the destination folder is known, so to avoid having to lookup the id of the folder a relativePath form field can be provided as shown in the screenshot below. You can try this for yourself via the 6th request in the Postman collection.
This will create a file named "my-file.txt" in the folder we created earlier i.e. in "/Company Home/User Homes/test/My Folder". The same thing can be achieved whilst creating folders and empty files by using the same named property in the body as follows:
{
...
"relativePath": "/My Folder"
}
Another feature of the repository we can control when uploading content is the generation of a rendition. To have the thumbnail rendition used by Share generated, provide a renditions form field with a value of doclib as shown in the screenshot below. You can try this for yourself via the 7th request in the Postman collection.
Currently only one rendition can be requested, we plan to allow multiple in the future hence the plural form field name.
Finally, let's take a look at how we set properties. Any other form field will be presumed to represent a property to set. The screenshot below and the last request in the Postman collection shows how to set the cm:title, cm:description and exif:manufacturer properties. Properties have to follow the prefix:localname format and be a registered property via the content model otherwise they are silently ignored.
If we take a look at the response we'll see that the appropriate aspects have also been automatically applied.
{
"entry": {
...
"aspectNames": [
"cm:versionable","cm:titled","cm:auditable","cm:author","exif:exif"
],
"properties": {
"cm:title": "The Title",
"cm:versionType": "MAJOR",
"cm:versionLabel": "1.0",
"exif:manufacturer": "Canon",
"cm:description":"The Description"
}
}
}
We've covered a lot of ground in this post but we still haven't looked at all the capabilities available; overwriting, versioning, custom types and associations will all be covered in future posts. we'll be looking at how to retrieve, update and delete files & folders.