Message Boards API Basics
Liferay’s Headless Delivery application provides REST services for the Message Boards application. With these services, you can add message board categories, threads, and messages, list their information, modify their content, or remove them altogether. Here you’ll call those services using cURL commands and Java classes.
Message board categories are named sections in the Liferay back-end. These sections define topics for organizing threads.
Preparing Tutorial Resources
Before proceeding with the tutorial, first set up a clean Liferay Docker container and prepare the provided tutorial code for use.
Liferay Docker Container
Start a new Liferay instance by running
docker run -it -m 8g -p 8080:8080 liferay/portal:7.4.3.55-ga55
Sign in to Liferay at http://localhost:8080. Use the email address [email protected] and the password test. When prompted, change the password to learn.
Once started, retrieve the site ID. To find your site ID, open the Site Menu () and go to Configuration → Site Settings → Site Configuration.
Tutorial Code
Below is sample code to demonstrate the Headless API. This code includes both sample cURL and Java files.
Run the following command to download and unzip the sample code:
curl https://resources.learn.liferay.com/dxp/latest/en/collaboration-and-social/message-boards/developer-guide/liferay-y3a6.zip -O
unzip liferay-y3a6.zip
While the cURL scripts come ready for use, you must compile the Java source files manually before you can run them. To do this, go to the project’s java
folder and run the javac
command.
cd liferay-y3a6/java
javac -classpath .:* *.java
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 provided code includes APIs for the MessageBoardSection
, MessageBoardThread
and MessageBoardMessage
services. See Tutorial Code Reference for a list of all included sample APIs.
The provided code uses basic authentication for demonstration purposes. For production, you should authorize users with OAuth2.
Calling the Sample APIs
In this exercise, you can use either the cURL commands or Java classes to call the MessageBoardSection
, MessageBoardThread
and MessageBoardMessage
APIs. The following output examples correspond to the cURL commands, which differ slightly from the output for the provided Java classes.
Navigate to the
curl
orjava
folder in theliferay-y3a6
project.For cURL:
cd liferay-y3a6/curl
For Java:
cd liferay-y3a6/java
Execute
MessageBoardSection_POST_ToSite
using your site ID as a parameter. This creates a new message board section in the specified site.For cURL:
./MessageBoardSection_POST_ToSite.sh {site-id}
For Java:
java -classpath .:* -DsiteId={site-id} MessageBoardSection_POST_ToSite
The terminal displays the complete schema for the newly created section. The provided API calls only define the
description
andname
fields for the new section.Copy the section’s ID for use with the following GET, PATCH, PUT, and DELETE methods.
{ ... "description" : "Foo", "id" : 43925, ... "name" : "Able Section", ... }
Execute
MessageBoardSections_GET_FromSite
using the site ID for its parameter. This returns a list of all sections in the specified site.For cURL:
./MessageBoardSections_GET_FromSite.sh {site-id}
For Java:
java -classpath .:* -DsiteId={site-id} MessageBoardSections_GET_FromSite
Execute
MessageBoardSection_PATCH_ById
using the message board section’s ID for its parameter. This updates the details of the specified section with those provided in the API call.For cURL:
./MessageBoardSection_PATCH_ById.sh {message-board-section-id}
For Java:
java -classpath .:* -DmessageBoardSectionId={message-board-section-id} MessageBoardSection_PATCH_ById
This updates the
description
field toBar
.Execute
MessageBoardSection_PUT_ById
using the same section ID for its parameter. This replaces the details of the specified section with those provided in the API call.For cURL:
./MessageBoardSection_PUT_ById.sh {message-board-section-id}
For Java:
java -classpath .:* -DmessageBoardSectionId={message-board-section-id} MessageBoardSection_PUT_ById
This updates the
name
field toBaker Section
and thedescription
field toGoo
.Execute
MessageBoardThread_POST_ToSite
using the site ID for its parameter. This creates a new message board thread for the site.For cURL:
./MessageBoardThread_POST_ToSite.sh {site-id}
For Java:
java -classpath .:* -DsiteId={site-id} MessageBoardThread_POST_ToSite
{ ... "articleBody" : "Foo", ... "headline" : "Able Thread", "id" : 43942, ... "messageBoardRootMessageId" : 43941, }
All threads are created with a root message that serves as the parent message of all direct replies in the thread (i.e.,
messageBoardRootMessageId
).Execute
MessageBoardThread_POST_ToSection
using the above section ID for its parameter. This creates a new message board thread for the specified section.For cURL:
./MessageBoardThread_POST_ToSection.sh {message-board-section-id}
For Java:
java -classpath .:* -DmessageBoardSectionId={message-board-section-id} MessageBoardThread_POST_ToSection
Copy this thread’s ID for use with the following GET, PATCH, and PUT methods.
{ ... "articleBody" : "Foo", ... "headline" : "Baker Thread", "id" : 43934, ... "messageBoardRootMessageId" : 43933, "messageBoardSectionId" : 43925, ... }
Execute
MessageBoardThread_PATCH_ById
using the thread’s ID for its parameter. This updates the details of the specified thread with those provided in the API call.For cURL:
./MessageBoardThread_PATCH_ById.sh {message-board-thread-id}
For Java:
java -classpath .:* -DmessageBoardThreadId={message-board-thread-id} MessageBoardThread_PATCH_ById
This updates the
articleBody
field toBar
.Execute
MessageBoardThread_PUT_ById
using the same thread ID for its parameter. This replaces the details of the specified thread with those provided in the API call.For cURL:
./MessageBoardThread_PUT_ById.sh {message-board-thread-id}
For Java:
java -classpath .:* -DmessageBoardThreadId={message-board-thread-id} MessageBoardThread_PUT_ById
This updates the
headline
field toCharlie Thread
and thearticleBody
field toGoo
.Execute the
MessageBoardThreads_GET_FromSite
using the site ID for its parameter. This returns a list of all site threads without a section.For cURL:
./MessageBoardThreads_GET_FromSite.sh {site-id}
For Java:
java -classpath .:* -DsiteId={site-id} MessageBoardThreads_GET_FromSite
Execute
MessageBoardThreads_GET_FromSection
using the section ID for its parameter. This returns a list of all threads in the specified section.For cURL:
./MessageBoardThreads_GET_FromSection.sh {message-board-section-id}
For Java:
java -classpath .:* -DmessageBoardSectionId={message-board-section-id} MessageBoardThreads_GET_FromSection
Execute
MessageBoardMessage_POST_ToThread
using either of the above thread IDs for its parameter. This creates a new message board message for the specified thread.For cURL:
./MessageBoardMessage_POST_ToThread.sh {message-board-thread-id}
For Java:
java -classpath .:* -DmessageBoardThreadId={message-board-thread-id} MessageBoardMessage_POST_ToThread
Copy the message’s ID for use with the following PUT, PATCH, and POST commands.
{ ... "articleBody" : "Foo", ... "headline" : "Able Message", "id" : 43946, ... "messageBoardSectionId" : 43925, "messageBoardThreadId" : 43934, "parentMessageBoardMessageId" : 43933, ... }
The new message is created as a child of the thread’s root message (
messageBoardRootMessageId
).Execute
MessageBoardMessage_PATCH_ById
using the message’s ID for its parameter. This updates the details of the specified message with those provided in the API call.For cURL:
./MessageBoardMessage_PATCH_ById.sh {message-board-message-id}
For Java:
java -classpath .:* -DmessageBoardMessageId={message-board-message-id} MessageBoardMessage_PATCH_ById
This updates the
articleBody
field toBar
.Execute
MessageBoardMessage_PUT_ById
using the same message ID for its parameter. This replaces the details of the specified message with those provided in the API call.For cURL:
./MessageBoardMessage_PUT_ById.sh {message-board-message-id}
For Java:
java -classpath .:* -DmessageBoardMessageId={message-board-message-id} MessageBoardMessage_PUT_ById
This updates the
headline
field toBaker Message
and thearticleBody
field toGoo
.Execute
MessageBoardMessage_POST_ToParent
using the preceding message ID for its parameter. This creates a new child message for the specified message.For cURL:
./MessageBoardMessage_POST_ToParent.sh {parent-message-board-message-id}
For Java:
java -classpath .:* -DparentMessageBoardMessageId={parent-message-board-message-id} MessageBoardMessage_POST_ToParent
{ ... "articleBody" : "Foo", ... "headline" : "Charlie Message", "id" : 43949, ... "messageBoardSectionId" : 43925, "messageBoardThreadId" : 43934, ... "parentMessageBoardMessageId" : 43946, ... }
Execute
MessageBoardMessages_GET_FromThread
using the thread ID for its parameter. This returns a list of child messages for the thread’s root message (i.e.,messageBoardRootMessage
).For cURL:
./MessageBoardMessages_GET_FromThread.sh {message-board-thread-id}
For Java:
java -classpath .:* -DmessageBoardThreadId={message-board-thread-id} MessageBoardMessages_GET_FromThread
The output should include data for the first message you created in the thread, which should itself have one child message. This is indicated by the message’s
numberOfMessageBoardMessages
field.Execute
MessageBoardMessages_GET_FromParent
using the preceding message’s ID for its parameter. This returns a list of all child messages for the specified Message.For cURL:
./MessageBoardMessages_GET_FromParent.sh {parent-message-board-message-id}
For Java:
java -classpath .:* -DparentMessageBoardMessageId={parent-message-board-message-id} MessageBoardMessages_GET_FromParent
The output should include data for the last child message you created.
Execute
MessageBoardSection_DELETE_ById
using the same section ID for its parameter. This deletes the specified section along with its threads and messages.For cURL:
./MessageBoardSection_DELETE_ById.sh {message-board-section-id}
For Java:
java -classpath .:* -DmessageBoardSectionId={message-board-section-id} MessageBoardSection_DELETE_ById
Execute
MessageBoardSection_GET_ById
using the same section ID for its parameter. This returns the details for the specified section if it exists.For cURL:
./MessageBoardSection_GET_ById.sh {message-board-section-id}
For Java:
java -classpath .:* -DmessageBoardSectionId={message-board-section-id} MessageBoardSection_GET_ById
Since you deleted the section in the preceding step, it returns the following message.
{ "status" : "NOT_FOUND", "title" : "No MessageBoardSection exists with the primary key 43925" }
Code Reference
The provided sample code includes cURL scripts and Java classes for the following MessageBoardSection
, MessageBoardThread
and MessageBoardMessage
APIs.
Sample MessageBoardSection APIs
The sample code includes cURL scripts and Java classes that call the following APIs.
Service | HTTP Method | HTTP Endpoint | Description |
---|---|---|---|
MessageBoardSection | POST |
/v1.0/sites/[siteId]/message-board-sections |
Creates a new category with the details provided in the API call |
MessageBoardSection | GET |
/v1.0/sites/[siteId]/message-board-sections |
Returns a complete list of all categories in the specified site; results can be paginated, filtered, searched, and sorted |
MessageBoardSection | PATCH |
/v1.0/message-board-sections/[messageBoardSectionId] |
Updates only the fields specified in the API call for a category |
MessageBoardSection | PUT |
/v1.0/message-board-sections/[messageBoardSectionId] |
Replaces all fields for the specified category with those provided in the API call |
MessageBoardSection | DELETE |
/v1.0/message-board-sections/[messageBoardSectionId] |
Deletes the specified category and returns a 204 if the operation succeeds |
Sample MessageBoardThread APIs
Service | HTTP Method | HTTP Endpoint | Description |
---|---|---|---|
MessageBoardThread | POST |
/v1.0/sites/[siteId]/message-board-threads |
Creates a new thread with the details provided in the API call |
MessageBoardThread | POST |
/v1.0/message-board-sections/[messageBoardSectionId]/message-board-threads |
Creates a new thread within the specified category using the details provided in the API call |
MessageBoardThread | GET |
/v1.0/sites/[siteId]/message-board-threads |
Returns a complete list of all site threads that are not in a category; results can be paginated, filtered, searched, and sorted |
MessageBoardThread | GET |
/v1.0/message-board-sections/[messageBoardSectionId]/message-board-threads |
Returns a complete list of all threads in the specified category; results can be paginated, filtered, searched, and sorted |
MessageBoardThread | PATCH |
/v1.0/message-board-threads/[messageBoardThreadId] |
Updates only the fields specified in the API call for a thread |
MessageBoardThread | PUT |
/v1.0/message-board-threads/[messageBoardThreadId] |
Replaces all fields for the specified thread with those provided in the API call |
MessageBoardThread | DELETE |
/v1.0/message-board-threads/[messageBoardThreadId] |
Deletes the specified thread and returns a 204 if the operation succeeds |
Sample MessageBoardMessage APIs
Service | HTTP Method | HTTP Endpoint | Description |
---|---|---|---|
MessageBoardMessage | POST |
/v1.0/message-board-threads/[messageBoardThreadId]/message-board-messages |
Creates a new message in the specified thread with the detailed provided in the API call. |
MessageBoardMessage | GET |
/v1.0/message-board-threads/[messageBoardThreadId]/message-board-messages |
Returns a complete list of all messages in the specified thread; results can be paginated, filtered, searched, and sorted |
MessageBoardMessage | PATCH |
/v1.0/message-board-messages/[messageBoardMessageId] |
Updates only the fields specified in the API call for a message |
MessageBoardMessage | PUT |
/v1.0/message-board-messages/[messageBoardMessageId] |
Replaces all fields for the specified message with those provided in the API call |
MessageBoardMessage | DELETE |
/v1.0/message-board-messages/[messageBoardMessageId] |
Deletes the specified message and returns a 204 if the operation succeeds |
Examining the Sample cURL Scripts
The following are representative examples of the tutorial’s cURL commands.
MessageBoardSection_POST_ToSite.sh
curl \
-H 'Content-Type: application/json' \
-X 'POST' "http://localhost:8080/o/headless-delivery/v1.0/sites/${1}/message-board-sections" \
-d "{\"description\": \"Foo\", \"title\": \"Able Section\"}" \
-u "[email protected]:learn"
MessageBoardSection_PUT_ById.sh
curl \
-H 'Content-Type: application/json' \
-X 'PUT' \
"http://localhost:8080/o/headless-delivery/v1.0/message-board-sections/${1}" \
-d "{\"description\": \"Goo\", \"title\": \"Baker Section\"}" \
-u "[email protected]:learn"
MessageBoardSections_GET_FromSite.sh
curl \
"http://localhost:8080/o/headless-delivery/v1.0/sites/${1}/message-board-sections" \
-u "[email protected]:learn"
MessageBoardSection_DELETE_ById.sh
curl \
-X 'DELETE' \
"http://localhost:8080/o/headless-delivery/v1.0/message-board-sections/${1}" \
-u "[email protected]:learn"
MessageBoardThread_POST_ToSection.sh
curl \
-H 'Content-Type: application/json' \
-X 'POST' "http://localhost:8080/o/headless-delivery/v1.0/message-board-sections/${1}/message-board-threads" \
-d "{\"articleBody\": \"Foo\", \"headline\": \"Baker Thread\"}" \
-u "[email protected]:learn"
MessageBoardMessage_POST_ToThread.sh
curl \
-H 'Content-Type: application/json' \
-X 'POST' "http://localhost:8080/o/headless-delivery/v1.0/message-board-threads/${1}/message-board-messages" \
-d "{\"articleBody\": \"Foo\", \"headline\": \"Able Message\"}" \
-u "[email protected]:learn"
MessageBoardMessage_POST_ToParent.sh
curl \
-H 'Content-Type: application/json' \
-X 'POST' "http://localhost:8080/o/headless-delivery/v1.0/message-board-messages/${1}/message-board-messages" \
-d "{\"articleBody\": \"Foo\", \"headline\": \"Charlie Message\"}" \
-u "[email protected]:learn"
Examining the Sample Java Classes
The following are representative examples of the tutorial’s Java commands.
MessageBoardSection_POST_ToSite.java
public class MessageBoardSection_POST_ToSite {
/**
* java -classpath .:* -DsiteId=1234 MessageBoardSection_POST_ToSite
*/
public static void main(String[] args) throws Exception {
MessageBoardSectionResource.Builder builder =
MessageBoardSectionResource.builder();
MessageBoardSectionResource messageBoardSectionResource =
builder.authentication(
"[email protected]", "learn"
).build();
MessageBoardSection messageBoardSection =
messageBoardSectionResource.postSiteMessageBoardSection(
Long.valueOf(System.getProperty("siteId")),
new MessageBoardSection() {
{
description = "Foo";
title = "Charlie Section";
}
});
System.out.println(messageBoardSection);
}
}
MessageBoardSection_PUT_ById.java
public class MessageBoardSection_PUT_ById {
/**
* java -classpath .:* -DmessageBoardSectionId=1234 MessageBoardSection_PUT_ById
*/
public static void main(String[] args) throws Exception {
MessageBoardSectionResource.Builder builder =
MessageBoardSectionResource.builder();
MessageBoardSectionResource messageBoardSectionResource =
builder.authentication(
"[email protected]", "learn"
).build();
MessageBoardSection messageBoardSection =
messageBoardSectionResource.putMessageBoardSection(
Long.valueOf(System.getProperty("messageBoardSectionId")),
new MessageBoardSection() {
{
description = "Goo";
title = "Dog Section";
}
});
System.out.println(messageBoardSection);
}
}
MessageBoardSections_GET_FromSite.java
public class MessageBoardSections_GET_FromSite {
/**
* java -classpath .:* -DsiteId=1234 MessageBoardSections_GET_FromSite
*/
public static void main(String[] args) throws Exception {
MessageBoardSectionResource.Builder builder =
MessageBoardSectionResource.builder();
MessageBoardSectionResource messageBoardSectionResource =
builder.authentication(
"[email protected]", "learn"
).build();
Page<MessageBoardSection> page =
messageBoardSectionResource.getSiteMessageBoardSectionsPage(
Long.valueOf(System.getProperty("siteId")), null, null, null,
null, Pagination.of(1, 2), null);
System.out.println(page);
}
}
MessageBoardSection_DELETE_ById.java
public class MessageBoardSection_DELETE_ById {
/**
* java -classpath .:* -DmessageBoardSectionId=1234 MessageBoardSection_DELETE_ById
*/
public static void main(String[] args) throws Exception {
MessageBoardSectionResource.Builder builder =
MessageBoardSectionResource.builder();
MessageBoardSectionResource messageBoardSectionResource =
builder.authentication(
"[email protected]", "learn"
).build();
messageBoardSectionResource.deleteMessageBoardSection(
Long.valueOf(System.getProperty("messageBoardSectionId")));
}
}
MessageBoardThread_POST_ToSection.java
public class MessageBoardThread_POST_ToSection {
/**
* java -classpath .:* -DmessageBoardSectionId=1234 MessageBoardThread_POST_ToSection
*/
public static void main(String[] args) throws Exception {
MessageBoardThreadResource.Builder builder =
MessageBoardThreadResource.builder();
MessageBoardThreadResource messageBoardThreadResource =
builder.authentication(
"[email protected]", "learn"
).build();
MessageBoardThread messageBoardThread =
messageBoardThreadResource.
postMessageBoardSectionMessageBoardThread(
Long.valueOf(System.getProperty("messageBoardSectionId")),
new MessageBoardThread() {
{
articleBody = "Foo";
headline = "Easy Thread";
}
});
System.out.println(messageBoardThread);
}
}
MessageBoardMessage_POST_ToThread.java
public class MessageBoardMessage_POST_ToThread {
/**
* java -classpath .:* -DmessageBoardThreadId=1234 MessageBoardMessage_POST_ToThread
*/
public static void main(String[] args) throws Exception {
MessageBoardMessageResource.Builder builder =
MessageBoardMessageResource.builder();
MessageBoardMessageResource messageBoardMessageResource =
builder.authentication(
"[email protected]", "learn"
).build();
MessageBoardMessage messageBoardMessage =
messageBoardMessageResource.
postMessageBoardThreadMessageBoardMessage(
Long.valueOf(System.getProperty("messageBoardThreadId")),
new MessageBoardMessage() {
{
articleBody = "Foo";
headline = "Dog Message";
}
});
System.out.println(messageBoardMessage);
}
}
MessageBoardMessage_POST_ToParent.java
public class MessageBoardMessage_POST_ToParent {
/**
* java -classpath .:* -DparentMessageBoardMessageId=1234 MessageBoardMessage_POST_ToParent
*/
public static void main(String[] args) throws Exception {
MessageBoardMessageResource.Builder builder =
MessageBoardMessageResource.builder();
MessageBoardMessageResource messageBoardMessageResource =
builder.authentication(
"[email protected]", "learn"
).build();
MessageBoardMessage messageBoardMessage =
messageBoardMessageResource.
postMessageBoardMessageMessageBoardMessage(
Long.valueOf(
System.getProperty("parentMessageBoardMessageId")),
new MessageBoardMessage() {
{
articleBody = "Foo";
headline = "Fox Message";
}
});
System.out.println(messageBoardMessage);
}
}