Document API Basics
Liferay’s headless delivery application provides REST services for Documents and Media that add documents and folders, list their information, modify them, delete them, and more. You can call those services using cURL commands and Java classes.
Liferay DXP 2024.Q4+ External Reference Codes (ERCs) are accessible for document entries, folders, types, metadata sets, and shortcuts, providing a consistent way to identify and access these elements across Liferay.
Start with uploading documents using an example cURL command and Java class.
Post a Document
Start a new Liferay instance by running
docker run -it -m 8g -p 8080:8080 liferay/portal:7.4.3.112-ga112
Sign in to Liferay at http://localhost:8080. Use the email address test@liferay.com and the password test. When prompted, change the password to learn.
When signed in, retrieve the site’s ID. Use this ID in several service calls.
Then, follow these steps:
-
Download and unzip the example project:
curl https://resources.learn.liferay.com/dxp/latest/en/content-authoring-and-management/documents-and-media/developer-guide/liferay-g9i6.zip -O
unzip liferay-g9i6.zip
Use a cURL script to upload a file to Documents and Media.
-
On the command line, navigate to the
curl
folder.cd liferay-g9i6.zip/curl
-
Upload a file by executing the
Documents_POST_ToSites.sh
script with your site ID as a parameter. For example,./Documents_POST_ToSites.sh 1234
NoteIf your user and password aren’t
test@liferay.com
andlearn
, respectively, replace those values in theDocuments_POST_ToSites.sh
script before running it.
The script uploads itself to your site’s Documents and Media.
The command response describes the new Documents and Media file in JSON, like this:
{
...
"description": "",
...
"id": 38301,
...
"title": "Documents_POST_ToSites.sh"
}
The response includes the file’s description, newly assigned ID, title, and more. Note the id
value for later commands.
Next, use a Java class to upload a file.
-
Go to the
java
folder and compile the Java source files.cd ../java
javac -classpath .:* *.java
-
Upload a file to Documents and Media by running the
Documents_POST_ToSites
class below, replacing thesiteId
system property value with your site’s ID.java -classpath .:* -DsiteId=1234 Documents_POST_ToSites
NoteIf your user and password aren’t
test@liferay.com
andtest
, respectively, replace those values in theDocuments_POST_ToSites.java
file and recompile the class before running it.
The class uploads its source file Documents_POST_ToSites.java
to Documents and Media.
Read on to see how the cURL command and Java class work.
Examine the cURL Command
The Documents_POST_ToSites.sh
script uploads a file by calling a headless-delivery
application REST service with cURL.
curl \
"http://localhost:8080/o/headless-delivery/v1.0/sites/${1}/documents" \
--form "file=@Document_POST_ToSite.sh" \
--header "Content-Type: multipart/form-data" \
--request "POST" \
--user "test@liferay.com:learn"
Here are the command’s arguments:
Arguments | Description |
---|---|
-F "file=@Documents_POST_ToSites.sh" | The file to post. |
-H "Content-Type: multipart/form-data" | The media type (MIME type) being posted. |
-X POST | The HTTP method to invoke at the specified endpoint. |
"http://localhost:8080/o/headless-delivery/v1.0/sites/${1}/documents" | The REST service endpoint. Your site ID parameter replaces ${1} . |
-u "test@liferay.com:learn" | Basic authentication credentials. |
Basic authentication is used here for demonstration purposes. For production, you should authorize users via OAuth 2.0. See Using OAuth2 to Authorize Users for a sample React application that uses OAuth2.
Other cURL commands for the Document
and DocumentFolder
REST services use similar arguments.
Next, see how similar the Java call is.
Examine the Java Class
The Documents_POST_ToSites.java
class uploads a file by calling a headless-delivery
application REST service.
public static void main(String[] args) throws Exception {
DocumentResource.Builder builder = DocumentResource.builder();
DocumentResource documentResource = builder.authentication(
"test@liferay.com", "learn"
).build();
System.out.println(
documentResource.postSiteDocument(
Long.valueOf(System.getProperty("siteId")), new Document(),
new HashMap<String, File>() {
{
put("file", new File("Documents_POST_ToSites.java"));
}
}));
}
This class invokes the REST service using only three lines of code:
Line (abbreviated) | Description |
---|---|
DocumentResource.Builder builder = ... | Gets a Builder for generating a DocumentResource service instance. |
DocumentResource documentResource = builder.authentication(...).build(); | Specifies basic authentication and generates a DocumentResource service instance. |
Document document = documentResource.postSiteDocument(...); | Calls the DocumentResource.postSiteDocument method, passing in a site ID, a Document object to represent the uploaded file, and a hash map that specifies the file to upload. The file is arbitrary–this example uses the local file Documents_POST_ToSites.java for convenience. |
Note that the project includes the com.liferay.headless.delivery.client.jar
file as a dependency. You can find client JAR dependency information for all REST applications in the API explorer in your installation at /o/api
.
The main
method’s comment demonstrates running the class.
The other example Java classes are similar to this one, but call different DocumentResource
methods.
See DocumentResource for service details.
Below are examples of calling other Document
REST services using cURL and Java.
Get Site Documents
You can list a site’s documents by executing the following cURL or Java command. As above, replace 1234
with your site’s ID.
Documents_GET_FromSites.sh
Command:
./Documents_GET_FromSites.sh 1234
Code:
curl \
"http://localhost:8080/o/headless-delivery/v1.0/sites/${1}/documents" \
--user "test@liferay.com:learn"
Documents_GET_FromSites.java
Command:
java -classpath .:* -DsiteId=1234 Documents_GET_FromSites
Code:
DocumentResource documentResource = builder.authentication(
"test@liferay.com", "learn"
).build();
System.out.println(
documentResource.getSiteDocumentsPage(
Long.valueOf(System.getProperty("siteId")), null, null, null,
null, Pagination.of(1, 2), null));
}
}
The site’s Document
objects are included in the JSON response.
{
"actions": {
"updateBatch": {
"method": "PUT",
"href": "http://localhost:8080/o/headless-delivery/v1.0/documents/batch"
},
"get": {
"method": "GET",
"href": "http://localhost:8080/o/headless-delivery/v1.0/sites/1234/documents"
},
"create": {
"method": "POST",
"href": "http://localhost:8080/o/headless-delivery/v1.0/sites/1234/documents"
},
"createBatch": {
"method": "POST",
"href": "http://localhost:8080/o/headless-delivery/v1.0/sites/1234/documents/batch"
},
"deleteBatch": {
"method": "DELETE",
"href": "http://localhost:8080/o/headless-delivery/v1.0/documents/batch"
}
},
"facets": [],
"items": [
{
"actions": {
"get-rendered-content-by-display-page": {
"method": "GET",
"href": "http://localhost:8080/o/headless-delivery/v1.0/documents/32131/rendered-content-by-display-page/{displayPageKey}"
},
"get": {
"method": "GET",
"href": "http://localhost:8080/o/headless-delivery/v1.0/documents/32131"
},
"replace": {
"method": "PUT",
"href": "http://localhost:8080/o/headless-delivery/v1.0/documents/32131"
},
"update": {
"method": "PATCH",
"href": "http://localhost:8080/o/headless-delivery/v1.0/documents/32131"
},
"delete": {
"method": "DELETE",
"href": "http://localhost:8080/o/headless-delivery/v1.0/documents/32131"
}
},
"adaptedImages": [
{
"contentUrl": "/o/adaptive-media/image/32131/Preview-1000x0/seahorse.jpg?t=1715340699885",
"height": 1510,
"resolutionName": "Preview-1000x0",
"sizeInBytes": 127254,
"width": 1000
},
{
"contentUrl": "/o/adaptive-media/image/32131/Thumbnail-300x300/seahorse.jpg?t=1715340699885",
"height": 300,
"resolutionName": "Thumbnail-300x300",
"sizeInBytes": 10927,
"width": 199
}
],
"contentUrl": "/documents/1234/0/seahorse.jpg/4be7d2ff-b9ac-a7ab-1081-537536ece7d9?version=1.0&t=1715340699885&download=true",
"creator": {
"additionalName": "",
"contentType": "UserAccount",
"familyName": "Test",
"givenName": "Test",
"id": 20122,
"name": "Test Test"
},
"customFields": [],
"dateCreated": "2024-05-10T11:29:14Z",
"dateModified": "2024-05-10T11:31:39Z",
"description": "",
"documentFolderId": 0,
"documentType": {
"availableLanguages": [],
"contentFields": [],
"description": "",
"name": "Basic Document"
},
"encodingFormat": "image/jpeg",
"externalReferenceCode": "4be7d2ff-b9ac-a7ab-1081-537536ece7d9",
"fileExtension": "jpg",
"fileName": "seahorse.jpg",
"friendlyUrlPath": "seahorse-friendly-url",
"id": 32131,
"keywords": [],
"numberOfComments": 0,
"relatedContents": [],
"renderedContents": [],
"siteId": 1234,
"sizeInBytes": 792227,
"taxonomyCategoryBriefs": [],
"title": "seahorse"
}
],
"lastPage": 1,
"page": 1,
"pageSize": 20,
"totalCount": 1
}
From the response, you can extract several pieces of information such as
-
A list of actions that can be performed on the document, including getting, updating, replacing, or deleting.
-
The document’s
contentUrl
for accessing the document content. -
Information about the document’s
creator
, including name and ID. -
The
dateCreated
anddateModified
timestamps that indicate when the document was created and last modified, respectively. -
Liferay DXP 2024.Q2+/Portal 7.4 GA120+
The document's [
friendlyUrlPath](../uploading-and-managing/configuring-document-urls.md) that can be the file’s name or a customized value set by the user.
Get a Document
You can get a Document
’s fields by executing the following cURL or Java command. Replace 1234
with the Document
’s ID.
Use Documents_GET_FromSites.[java|sh]
to get site Document
IDs.
Documents_GET_ById.sh
Command:
./Documents_GET_ById.sh 1234
Code:
curl \
"http://localhost:8080/o/headless-delivery/v1.0/documents/${1}" \
--user "test@liferay.com:learn"
Documents_GET_ById.java
Command:
java -classpath .:* -DdocumentId=1234 Documents_GET_ById
Code:
public static void main(String[] args) throws Exception {
DocumentResource.Builder builder = DocumentResource.builder();
DocumentResource documentResource = builder.authentication(
"test@liferay.com", "learn"
).build();
System.out.println(
documentResource.getDocument(
Long.valueOf(System.getProperty("documentId"))));
}
The Document
fields are included in the JSON response.
Get Document Content
Document
content is encoded in Base64 and embedded in the Document
’s nestedFields
. You can get the content by executing the following cURL or Java command. Replace 1234
with the Document
’s ID.
Documents_GET_ContentValue_ById.sh
Command:
./Documents_GET_ContentValue_ById.sh 1234
Code:
curl \
"http://localhost:8080/o/headless-delivery/v1.0/documents/${1}?nestedFields=contentValue&fields=contentValue" \
--user "test@liferay.com:learn" \
| sed -n "2 p" \
| awk -F ":" '{print $2}' \
| tr -d " \"" \
| base64 -d
The first argument line specifies the service endpoint and authentication credentials, respectively. The URL’s /o/headless-delivery/v1.0/documents/${1}
part is the REST service endpoint to get the Document
by its ID. This URL is the same as the Documents_GET_ById.sh
script’s URL. The ?nestedFields=contentValue
part requests the contentValue
embedded in the Document
’s nestedFields
. Lastly the &fields=contentValue
part filters on the contentValue
field, so that the content field alone is returned. Invoking only the service, however, returns Base64-encoded content wrapped in JSON, like this:
{
"contentValue" : "Y3VybCBcCgktRiAiZmlsZT1ARG9jdW1lbnRfUE9TVF9Ub1NpdGUuc2giIFwKCS1IICJDb250ZW50LVR5cGU6IG11bHRpcGFydC9mb3JtLWRhdGEiIFwKCS1YIFBPU1QgXAoJImh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9vL2hlYWRsZXNzLWRlbGl2ZXJ5L3YxLjAvc2l0ZXMvJHsxfS9kb2N1bWVudHMiIFwKCS11ICJ0ZXN0QGxpZmVyYXkuY29tOnRlc3Qi"
}
The routines following the service invocation process the encoded content. The sed
and awk
routines isolate the Document
content value and the tr
routine decodes it. Here’s the decoded content returned for the Documents_POST_ToSites.sh
Document
that you uploaded:
curl \
"http://localhost:8080/o/headless-delivery/v1.0/documents/${1}?nestedFields=contentValue&fields=contentValue" \
--user "test@liferay.com:learn" \
| sed -n "2 p" \
| awk -F ":" '{print $2}' \
| tr -d " \"" \
| base64 -d
Documents_GET_ContentValue_ById.java
The Java code to get Document
content and decode it is simpler than the previous cURL command.
Command:
java -classpath .:* -DdocumentId=1234 Documents_GET_ContentValue_ById
Code:
DocumentResource.Builder builder = DocumentResource.builder();
builder.parameter("nestedFields", "contentValue");
DocumentResource documentResource = builder.authentication(
"test@liferay.com", "learn"
).build();
System.out.println(
new String(
Base64.getDecoder(
).decode(
documentResource.getDocument(
Long.valueOf(System.getProperty("documentId"))
).getContentValue()
)));
}
Most of the code resembles the code in Documents_POST_ToSites.java
. There are a couple key differences.
The following line adds the contentValue
nested field as a request parameter.
builder.parameter("nestedFields", "contentValue");
After getting the Document
by its ID, a Base64.Decoder
decodes the Document
’s content.
Base64.Decoder decoder = Base64.getDecoder();
Patch a Document
Document
’s PATCH services update a Document
and its fields. You can update a Document
by executing the following cURL or Java command. Replace 1234
with the Document
’s ID.
Documents_PATCH_ById.sh
Command:
./Documents_PATCH_ById.sh 1234
Code:
curl \
"http://localhost:8080/o/headless-delivery/v1.0/documents/${1}" \
--form "document={\"description\": \"Bar\"}" \
--form "file=@Document_POST_ToSite.sh" \
--header "Content-Type: multipart/form-data; boundary=ARBITRARY" \
--request "PATCH" \
--user "test@liferay.com:learn"
The first form data part (following -F
) specifies a new value for the Document
’s description
field. The second form data part specifies the updated file to upload. Note, both are not required. You can patch only the file or only the document’s metadata.
Documents_PATCH_ById.java
Command:
java -classpath .:* -DdocumentId=1234 Documents_PATCH_ById
Code:
public static void main(String[] args) throws Exception {
DocumentResource.Builder builder = DocumentResource.builder();
DocumentResource documentResource = builder.authentication(
"test@liferay.com", "learn"
).build();
System.out.println(
documentResource.patchDocument(
Long.valueOf(System.getProperty("documentId")),
new Document() {
{
description = "Bar";
}
},
new HashMap<String, File>() {
{
put("file", new File("Document_POST_ToSite.java"));
}
}));
}
The Java code above calls DocumentResource
’s patchDocument
method, passing in the Document
’s ID, a Document
object that includes a field to update, and the updated file to upload.
The above commands update the Document
’s description to “Bar”.
Put a Document
Document
’s PUT services replace the Document
and its fields entirely. You can replace a Document
by executing the following cURL or Java command. Replace 1234
with the Document
’s ID.
Documents_PUT_ById.sh
Command:
./Documents_PUT_ById.sh 1234
Code:
curl \
"http://localhost:8080/o/headless-delivery/v1.0/documents/${1}" \
--form "document={\"description\": \"Goo\", \"title\": \"Document_PUT_ById.sh\"}" \
--form "file=@Document_PUT_ById.sh" \
--header "Content-Type: multipart/form-data; boundary=ARBITRARY" \
--request "PUT" \
--user "test@liferay.com:learn"
The first form data part sets new description
and title
field values. The second form data part specifies a replacement file to upload.
Documents_PUT_ById.java
Command:
java -classpath .:* -DdocumentId=1234 Documents_PUT_ById
Code:
public static void main(String[] args) throws Exception {
DocumentResource.Builder builder = DocumentResource.builder();
DocumentResource documentResource = builder.authentication(
"test@liferay.com", "learn"
).build();
System.out.println(
documentResource.putDocument(
Long.valueOf(System.getProperty("documentId")),
new Document() {
{
description = "Goo";
title = "Documents_PUT_ById.java";
}
},
new HashMap<String, File>() {
{
put("file", new File("Documents_PUT_ById.java"));
}
}));
}
The Java code above calls DocumentResource
’s putDocument
method, passing in the Document
’s ID, a Document
object that includes values for the Document
’s description
and title
fields, and a replacement file to upload.
The above cURL command and Java class replace Document
instances with completely new ones that have the new titles Documents_PUT_ById.sh
and Documents_PUT_ById.java
, respectively, and have the description Goo.
Unless you want to use the current Document
’s title, make sure to specify the title
value you want for the replacement Document
.
Delete a Document
You can delete a Document
by executing the following cURL or Java command. Replace 1234
with the Document
’s ID.
Documents_DELETE_ById.sh
Command:
./Documents_DELETE_ById.sh 1234
Code:
curl \
"http://localhost:8080/o/headless-delivery/v1.0/documents/${1}" \
--request "DELETE" \
--user "test@liferay.com:learn"
Documents_DELETE_ById.java
Command
java -classpath .:* -DdocumentId=1234 Documents_DELETE_ById
Code:
public static void main(String[] args) throws Exception {
DocumentResource.Builder builder = DocumentResource.builder();
DocumentResource documentResource = builder.authentication(
"test@liferay.com", "learn"
).build();
documentResource.deleteDocument(
Long.valueOf(System.getProperty("documentId")));
}
The Document
s are removed from Documents and Media.
More Document and Document Folder Services
The following cURL commands and Java classes demonstrate more Document
services and DocumentFolder
services.
Files | Description |
---|---|
Documents_POST_ToDocumentFolders.[java\|sh] | Posts a document to a folder. |
DocumentFolders_GET_ById.[java\|sh] | Lists a folder’s fields. |
DocumentFolders_PATCH_ById.[java\|sh] | Updates a folder and its fields. |
DocumentFolders_POST_ToSites.[java\|sh] | Posts a document folder to a site. |
DocumentFolders_PUT_ById.[java\|sh] | Replaces a folder and its fields entirely. |
DocumentFolders_DELETE_ById.[java\|sh] | Deletes a document folder. |
DocumentFolders_GET_FromSites.[java\|sh] | Lists a site’s folders. |
The API Explorer lists all of the Document
and DocumentFolder
services and schemas, and has an interface to try out each service.
See the DocumentResource and DocumentFolderResource Java interfaces too.