Object API Basics
When you publish an Object, Liferay automatically generates REST APIs for it. These APIs differ for Company and Site scoped Objects, but they all use the c/[pluralobjectlabel]
naming pattern (e.g., c/timeoffrequests
). You can use these APIs to create, access, update, and remove Object entries.
Here you’ll use cURL commands to perform basic CRUD operations for a custom Object. Before proceeding, set up a new Liferay DXP/Portal 7.4 instance and prepare the provided tutorial code.
For a complete list of APIs generated for both Site
and Company
objects, see Object’s Headless Framework Integration. You can view and test custom object APIs via the Liferay API Explorer at [server]:[port]/o/api
(e.g., localhost:8080/o/api
). They appear under REST Applications.
Setting Up a Liferay Instance
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.
Then, follow these steps to create a basic Object for this tutorial:
-
Open the Global Menu (
), go to the Control Panel tab, and click Objects.
-
Click the Add button (
) and enter these values:
Field Value Label Able
Plural Label Ables
Name Able
-
Select the new Object draft, go to the Fields tab, and add a single text field:
Label Field Name Type Required Name name Text ✔ -
Go to the Details tab and click Publish.
ImportantFor this tutorial, you must use the above values.
Publishing an Object creates and activates a new application for receiving and storing data. You can now access it via Headless APIs.
Preparing the Sample Code
Run the following commands to download and unzip the provided sample code:
curl https://resources.learn.liferay.com/dxp/latest/en/building-applications/objects/understanding-object-integrations/using-custom-object-apis/liferay-v1s4.zip -O
unzip liferay-v1s4.zip
These scripts include the following APIs:
HTTP Method | HTTP Endpoint | Description |
---|---|---|
GET | / | Returns a complete list of object entries in a Liferay instance; results can be paginated, filtered, searched, and sorted |
POST | / | Creates a new object entry using the details provided in the API call |
DELETE | /{objectNameId} | Deletes the specified object entry and returns a 204 if the operation succeeds |
GET | /{objectNameId} | Returns details for the specified object entry |
PUT | /{objectNameId} | Replaces the specified object entry’s details with those provided in the API call |
GET | /{objectNameId}/permissions | Returns details for the specified object entry permissions |
PUT | /{objectNameId}/permissions | Replaces the specified Object entry permission details with those provided in the API call |
Calling the Custom Object’s APIs
-
After downloading the sample code, navigate to the
curl
folder in theliferay-v1s4
project.cd liferay-v1s4/curl
-
Execute
Able_POST_ToCompany
. This creates three entries../Able_POST_ToCompany.sh
The terminal displays the complete schema for the newly created entries. Copy the first entry’s ID for use with the following methods.
{ "id" : 41969, ... "name" : "Able 1" } { "id" : 41971, ... "name" : "Able 2" } { "id" : 41973, ... "name" : "Able 3" }
-
Execute
Ables_GET_FromCompany
. This returns a list of the Object’s entries../Ables_GET_FromCompany.sh
-
Execute
Able_PUT_ById
with the first entry’s ID as a parameter. This replaces the details of the specified entry with the details provided in the API call../Able_PUT_ById.sh {entry-id}
{ "id" : 41969, ... "name" : "Able One" }
-
Execute
Able_DELETE_ById
with the same ID as its parameter. This deletes the specified entry../Able_DELETE_ById.sh {entry-id}
-
Execute
Able_GET_ById
with the same ID as its parameter. This returns the details for the specified entry if it exists../Able_GET_ById.sh {entry-id}
Since you deleted the entry in the preceding step, it returns the following message.
{ "status": "NOT_FOUND", "title": "No ObjectEntry exists with the primary key 41969" }
Examining the Sample cURL Scripts
The following are examples of the tutorial’s cURL commands.
Able_POST_ToCompany.sh
curl \
"http://localhost:8080/o/c/ables/" \
--data-raw '
{
"name": "Able 1"
}' \
--header "Content-Type: application/json" \
--request "POST" \
--user "test@liferay.com:learn"
curl \
"http://localhost:8080/o/c/ables/" \
--data-raw '
{
"name": "Able 2"
}' \
--header "Content-Type: application/json" \
--request "POST" \
--user "test@liferay.com:learn"
curl \
"http://localhost:8080/o/c/ables/" \
--data-raw '
{
"name": "Able 3"
}' \
--header "Content-Type: application/json" \
--request "POST" \
--user "test@liferay.com:learn"
Able_PUT_ById.sh
curl \
"http://localhost:8080/o/c/ables/${1}" \
--data-raw '
{
"name": "Able One"
}' \
--header "Content-Type: application/json" \
--request "PUT" \
--user "test@liferay.com:learn"
Managing Object Permissions
Use the object APIs to read and update permissions for object entries. See Objects Application Permissions for more information.
-
Execute
Able_GET_Permissions
to retrieve a list of object entry permissions../Able_GET_Permissions.sh {entry-id}
This example returns permissions for all roles. To retrieve permissions for a specific role, use the
roleNames
query parameter.curl \ "http://localhost:8080/o/c/ables/${1}/permissions?roleNames=Site Member" \ --user "test@liferay.com:learn"
In this example, the only role is Owner, and its permissions are: Delete, Permissions, Update, and View.
{ "actions": { "get": { "method": "GET", "href": "http://localhost:8080/o/c/ables/41969/permissions" }, "replace": { "method": "PUT", "href": "http://localhost:8080/o/c/ables/41969/permissions" } }, "facets": [], "items": [ { "actionIds": [ "DELETE", "PERMISSIONS", "UPDATE", "VIEW" ], "roleName": "Owner" } ], "lastPage": 1, "page": 1, "pageSize": 1, "totalCount": 1 }
-
Execute
Able_PUT_Permissions
with the entry ID as a parameter to replace the entry’s details with those provided in the API call../Able_PUT_Permissions.sh {entry-id}
The Update permission was removed from the Owner role.
{ "actions": { "get": { "method": "GET", "href": "http://localhost:8080/o/c/ables/41969/permissions" }, "replace": { "method": "PUT", "href": "http://localhost:8080/o/c/ables/41969/permissions" } }, "facets": [], "items": [ { "actionIds": [ "DELETE", "PERMISSIONS", "VIEW" ], "roleName": "Owner" } ], "lastPage": 1, "page": 1, "pageSize": 1, "totalCount": 1 }
Managing Object Tags and Categories
You can use the Object APIs to read, set, and update tags and categories for object entries that have categorization enabled. See Tags and Categories for more information.
Tags are represented by the keywords
property. You can set or update tags by adding a keywords
array to the body of any POST, PUT, or PATCH request.
"keywords" : [
"tag1", "tag2", "tag3"
]
After making a GET request for an object entry, you can read its tags in the same keywords
array.
You can set and update categories for an object entry by adding the taxonomyCategoryIds
array to any POST, PUT, or PATCH request.
"taxonomyCategoryIds" : [
1234, 5678
]
You must have an existing vocabulary of categories to assign categories to an object entry. See Defining Categories and Vocabularies for Content for more information.
After making a GET request for an object entry, you can read its categories in the taxonomyCategoryBriefs
array, which contains the taxonomyCategoryId
and taxonomyCategoryName
for each assigned category.
"taxonomyCategoryBriefs": [
{
"taxonomyCategoryId": 1234,
"taxonomyCategoryName": "Category A"
},
{
"taxonomyCategoryId": 5678,
"taxonomyCategoryName": "Category B"
}
]
You can filter object entries by keywords
and taxonomyCategoryIds
following the rules described in API Query Parameters. Example filter strings may look like these:
-
keywords/any(k:k in ('tag1','tag2'))
retrieves all object entries tagged withtag1
ortag2
. -
taxonomyCategoryIds/any(k:k in (1234,5678))
retrieves all entries linked to the category with ID1234
or5678
.
You can sort object entries by fields from related objects using the syntax described in API Query Parameters. Example sorting strings may look like these:
-
sort=relatedRelationship/fieldName:asc
sorts the entries based on a field from a directly related object in ascending order. -
sort=relatedRelationship1/relatedRelationship1/fieldName:desc
sorts the entries based on a field from a nested related object in descending order.