Using Relationship REST APIs
Liferay 7.4 U70+/GA70+
When you add relationships to custom or system objects, Liferay generates REST endpoints for accessing those relationships. You can relate and disassociate entries, as well as return an entry’s related entries. These endpoints are added to the parent object in one-to-many relationships and to both objects in many-to-many relationships.
To proceed, set up a new Liferay 7.4 instance and prepare the provided tutorial code. Then, run the scripts to create object entries and manage their relationships with one another.
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.132-ga132
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.
Next, create three related custom objects:
-
Open the Global Menu (
), go to the Control Panel tab, and click Objects. -
Create three object drafts.
First Object:
Field Value Label AblePlural Label AblesName AbleSecond Object:
Field Value Label BakerPlural Label BakersName BakerThird Object:
Field Value Label CharliePlural Label CharliesName Charlie -
Add the
namefield to each object draft.Label Field Name Type Required NamenameText ✔ -
Add these relationships to the able object:
Label Relationship Name Type Object Able to BakerableToBakerOne to Many Baker Able to CharlieableToCharlieOne to Many Charlie -
Publish each object.
Once published, you can access their REST APIs, including the following relationship APIs:
| Object | HTTP Method | HTTP Endpoint | Java Method |
|---|---|---|---|
| Able | GET | /{ableId}/ableToBaker | getAbleAbleToBakerBakerPage |
| Able | GET | /{ableId}/ableToCharlie | getAbleAbleToCharlieCharliePage |
| Able | DELETE | /{ableId}/ableToBaker/{bakerId} | deleteAbleAbleToBakerBaker |
| Able | PUT | /{ableId}/ableToBaker/{bakerId} | putAbleAbleToBakerBaker |
| Able | DELETE | /{ableId}/ableToCharlie/{charlieId} | deleteAbleAbleToCharlieCharlie |
| Able | PUT | /{ableId}/ableToCharlie/{charlieId} | putAbleAbleToCharlieCharlie |
| Able | PUT | /by-external-reference-code/{ableERC}/ableToBaker/{bakerERC} | putAbleAbleToBakerBaker |
| Able | PUT | /by-external-reference-code/{ableERC}/ableToCharlie/{charlieERC} | putAbleAbleToCharlieCharlie |
| Charlie | GET | /{charlieId}/ableToCharlie | getCharlieAbleToCharlieAblePage |
| Charlie | DELETE | /{charlieId}/ableToCharlie/{ableId} | deleteCharlieAbleToCharlieAble |
| Charlie | PUT | /{charlieId}/ableToCharlie/{ableId} | putCharlieAbleToCharlieAble |
| Charlie | PUT | /by-external-reference-code/{ableERC}/ableToCharlie/{charlieERC} | putCharlieAbleToCharlieAble |
For a complete list of APIs generated for site and company objects, see Objects 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). Click REST Applications and select an API.
Preparing the Sample Code
Run these commands to download and unzip the provided sample code:
curl https://resources.learn.liferay.com/examples/liferay-f9m2.zip -O
unzip liferay-f9m2.zip
The sample code includes commands for creating entries for each object and using their relationship APIs.
Using the Sample Code
Use the REST APIs to add object entries and manage their relationships:
-
Navigate to the
curlfolder in theliferay-f9m2project.cd liferay-f9m2/curl -
Run
POSTcommands to create three entries for each object. These entries have predefined external reference codes (ERCs) following the[objectname]-[number]naming pattern (e.g.,able-one)../Ables_POST_Batch.sh./Bakers_POST_Batch.sh./Charlies_POST_Batch.sh -
Run
Ables_PUT_AbleToBakers_ByExternalReferenceCodewith theable-oneERC and all three baker ERCs../Ables_PUT_AbleToBakers_ByExternalReferenceCode.sh able-one baker-one baker-two baker-threeThis relates the able entry with the baker entries and prints the response.
{ ... "externalReferenceCode" : "baker-one", "id" : 42427, ... "name" : "Baker 1", "r_ableToBaker_c_ableId" : 42421, "r_ableToBaker_c_ableERC" : "able-one" } { ... "externalReferenceCode" : "baker-two", "id" : 42429, ... "name" : "Baker 2", "r_ableToBaker_c_ableId" : 42421, "r_ableToBaker_c_ableERC" : "able-one" } { ... "externalReferenceCode" : "baker-three", "id" : 42431, ... "name" : "Baker 3", "r_ableToBaker_c_ableId" : 42421, "r_ableToBaker_c_ableERC" : "able-one" } -
Run
Ables_DELETE_AbleToBakers_ByIdwith two IDs: the ID forable-oneand the ID forbaker-three../Ables_DELETE_AbleToBaker_ById.sh {able-entry-id} {baker-entry-id}This disassociates the entries.
-
Run
Ables_GET_AbleToBaker_ByIdwith the same able ID to confirm they are no longer related../Ables_GET_AbleToBaker_ById.sh {able-entry-id}{ ... "externalReferenceCode" : "baker-two", "id" : 42429, ... "name" : "Baker 2", "r_ableToBaker_c_ableId" : 42421, "r_ableToBaker_c_ableERC" : "able-one" }, { ... "externalReferenceCode" : "baker-one", "id" : 42427, ... "name" : "Baker 1", "r_ableToBaker_c_ableId" : 42421, "r_ableToBaker_c_ableERC" : "able-one" } -
Run
Ables_PUT_AbleToCharlie_ByExternalReferenceCodewith theable-oneERC and all three charlie ERCs../Ables_PUT_AbleToCharlie_ByExternalReferenceCode.sh able-one charlie-one charlie-two charlie-threeThis relates the able entry with the charlie entries and prints the response.
{ ... "externalReferenceCode" : "charlie-one", "id" : 42433, ... "name" : "Charlie 1" } { ... "externalReferenceCode" : "charlie-two", "id" : 42435, ... "name" : "Charlie 2" } { ... "externalReferenceCode" : "charlie-three", "id" : 42437, ... "name" : "Charlie 3" } -
Run
Charlies_GET_AbleToCharlie_ByIdwith the ID forcharlie-one../Charlies_GET_AbleToCharlie_ById.sh {charlie-entry-id}This returns a list of all able entries related to the specified charlie entry.
{ ... "items" : [ { ... "externalReferenceCode" : "able-one", "id" : 42421, ... "name" : "Able 1" } ], "lastPage" : 1, "page" : 1, "pageSize" : 1, "totalCount" : 1 } -
Run
Charlies_PUT_AbleToCharlie_ByExternalReferenceCodewith thecharlie-oneandable-twoERCs../Charlies_PUT_AbleToCharlie_ByExternalReferenceCode.sh charlie-one able-twoThis relates the charlie entry to another able entry.
{ ... "externalReferenceCode" : "able-two", "id" : 42423, ... "name" : "Able 2" } -
Run
Charlies_GET_AbleToCharlie_ByIdwith the ID forcharlie-oneand confirm there are now two related able entries../Charlies_GET_AbleToCharlie_ById.sh {charlie-entry-id}{ ... "items" : [ { ... "externalReferenceCode" : "able-two", "id" : 42423, ... "name" : "Able 2" }, { ... "externalReferenceCode" : "able-one", "id" : 42421, ... "name" : "Able 1" } ], "lastPage" : 1, "page" : 1, "pageSize" : 2, "totalCount" : 2 } -
Run
Ables_GET_ByIdwith the ID forable-one../Ables_GET_ById.sh {able-entry-id}This command uses the
nestedFieldsparameter to return all related baker and charlie entries.{ "externalReferenceCode" : "able-one", "id" : 42421, ... "ableToCharlie" : [ { ... "externalReferenceCode" : "charlie-one", "id" : 42433, ... "name" : "Charlie 1" }, { ... "externalReferenceCode" : "charlie-two", "id" : 42435, ... "name" : "Charlie 2" }, { ... "externalReferenceCode" : "charlie-three", "id" : 42437, ... "name" : "Charlie 3" } ], "name" : "Able 1", "ableToBaker" : [ { ... "externalReferenceCode" : "baker-one", "id" : 42427, ... "name" : "Baker 1", "r_ableToBaker_c_ableId" : 42421, "r_ableToBaker_c_ableERC" : "able-one" }, { ... "externalReferenceCode" : "baker-two", "id" : 42429, ... "name" : "Baker 2", "r_ableToBaker_c_ableId" : 42421, "r_ableToBaker_c_ableERC" : "able-one" } ] }See Using nestedFields to Query Related Entries for more information on the
nestedFieldsparameter.
Examining the Code
Charlies_PUT_AbleToCharlie_ByExternalReferenceCode
curl \
"http://localhost:8080/o/c/charlies/by-external-reference-code/${1}/ableToCharlie/${2}" \
--header "Content-Type: application/json" \
--request "PUT" \
--user "test@liferay.com:learn"
Charlies_GET_AbleToCharlie_ById
curl \
"http://localhost:8080/o/c/charlies/${1}/ableToCharlie" \
--header "Content-Type: application/json" \
--user "test@liferay.com:learn"
Ables_DELETE_AbleToBaker_ById
curl \
"http://localhost:8080/o/c/ables/${1}/ableToBaker/${2}" \
--header "Content-Type: application/json" \
--request "DELETE" \
--user "test@liferay.com:learn"
Ables_GET_ById.sh
curl \
"http://localhost:8080/o/c/ables/${1}/?nestedFields=ableToBaker,ableToCharlie" \
--user "test@liferay.com:learn"