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

Next, create three related custom objects:

  1. Open the Global Menu (Global Menu), go to the Control Panel tab, and click Objects.

  2. Create three object drafts.

    First Object:

    Field Value
    Label Able
    Plural Label Ables
    Name Able

    Second Object:

    Field Value
    Label Baker
    Plural Label Bakers
    Name Baker

    Third Object:

    Field Value
    Label Charlie
    Plural Label Charlies
    Name Charlie
  3. Add the name field to each object draft.

    Label Field Name Type Required
    Name name Text
  4. Add these relationships to the able object:

    Label Relationship Name Type Object
    Able to Baker ableToBaker One to Many Baker
    Able to Charlie ableToCharlie One to Many Charlie
  5. 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
tip

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/dxp/latest/en/building-applications/objects/understanding-object-integrations/using-custom-object-apis/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:

  1. Navigate to the curl folder in the liferay-f9m2 project.

    cd liferay-f9m2/curl
    
  2. Run POST commands 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).

    ./Able_POST_Batch.sh
    
    ./Baker_POST_Batch.sh
    
    ./Charlie_POST_Batch.sh
    
  3. Run Able_PUT_AbleToBaker_ByExternalReferenceCode with the able-one ERC and all three baker ERCs.

    ./Able_PUT_AbleToBaker_ByExternalReferenceCode.sh able-one baker-one baker-two baker-three
    

    This 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"
    }
    
  4. Run Able_DELETE_AbleToBaker_ById with two IDs: the ID for able-one and the ID for baker-three.

    ./Able_DELETE_AbleToBaker_ById.sh {able-entry-id} {baker-entry-id}
    

    This disassociates the entries.

  5. Run Able_GET_AbleToBaker_ById with the same able ID to confirm they are no longer related.

    ./Able_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"
    }
    
  6. Run Able_PUT_AbleToCharlie_ByExternalReferenceCode with the able-one ERC and all three charlie ERCs.

    ./Able_PUT_AbleToCharlie_ByExternalReferenceCode.sh able-one charlie-one charlie-two charlie-three
    

    This 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"
    }
    
  7. Run Charlie_GET_AbleToCharlie_ById with the ID for charlie-one.

    ./Charlie_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
    }
    
  8. Run Charlie_PUT_AbleToCharlie_ByExternalReferenceCode with the charlie-one and able-two ERCs.

    ./Charlie_PUT_AbleToCharlie_ByExternalReferenceCode.sh charlie-one able-two
    

    This relates the charlie entry to another able entry.

    {
      ...
      "externalReferenceCode" : "able-two",
      "id" : 42423,
      ...
      "name" : "Able 2"
    }
    
  9. Run Charlie_GET_AbleToCharlie_ById with the ID for charlie-one and confirm there are now two related able entries.

    ./Charlie_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
    }
    
  10. Run Able_GET_ById with the ID for able-one.

    ./Able_GET_ById.sh {able-entry-id}
    

    This command uses the nestedFields parameter 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 nestedFields parameter.

Examining the Code

Charlie_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"

Charlie_GET_AbleToCharlie_ById

curl \
	"http://localhost:8080/o/c/charlies/${1}/ableToCharlie" \
	--header "Content-Type: application/json" \
	--user "test@liferay.com:learn"

Able_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"

Able_GET_ById.sh

curl \
	"http://localhost:8080/o/c/ables/${1}/?nestedFields=ableToBaker,ableToCharlie" \
	--user "test@liferay.com:learn"

Ask

Capabilities

Product

DXP

Contact Us

Connect

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