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.

Note

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:

  1. 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.

  1. On the command line, navigate to the curl folder.

    	cd liferay-g9i6.zip/curl
    
  2. 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
    
    Note

    If your user and password aren’t test@liferay.com and learn, respectively, replace those values in the Documents_POST_ToSites.sh script before running it.

The script uploads itself to your site’s Documents and Media.

The file uploaded to 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.

  1. Go to the java folder and compile the Java source files.

    cd ../java
    
    javac -classpath .:* *.java
    
  2. Upload a file to Documents and Media by running the Documents_POST_ToSites class below, replacing the siteId system property value with your site’s ID.

    java -classpath .:* -DsiteId=1234 Documents_POST_ToSites
    
    Note

    If your user and password aren’t test@liferay.com and test, respectively, replace those values in the Documents_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.

The Java class uploaded the Java source file.

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:

ArgumentsDescription
-F "file=@Documents_POST_ToSites.sh"The file to post.
-H "Content-Type: multipart/form-data"The media type (MIME type) being posted.
-X POSTThe 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.
Note

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.

Note

The main method’s comment demonstrates running the class.

The other example Java classes are similar to this one, but call different DocumentResource methods.

Important

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 and dateModified 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.

Tip

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”.

The cURL command changed the document's description.

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.

Warning

Unless you want to use the current Document’s title, make sure to specify the title value you want for the replacement Document.

The cURL command replaced the 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 Documents 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.

FilesDescription
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.

Capabilities

Product

Contact Us

Connect

Powered by Liferay
© 2024 Liferay Inc. All Rights Reserved • Privacy Policy