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

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:

    FieldValue
    LabelAble
    Plural LabelAbles
    NameAble

    Second Object:

    FieldValue
    LabelBaker
    Plural LabelBakers
    NameBaker

    Third Object:

    FieldValue
    LabelCharlie
    Plural LabelCharlies
    NameCharlie
  3. Add the name field to each object draft.

    LabelField NameTypeRequired
    NamenameText
  4. Add these relationships to the able object:

    LabelRelationship NameTypeObject
    Able to BakerableToBakerOne to ManyBaker
    Able to CharlieableToCharlieOne to ManyCharlie
  5. Publish each object.

Once published, you can access their REST APIs, including the following relationship APIs:

ObjectHTTP MethodHTTP EndpointJava Method
AbleGET/{ableId}/ableToBakergetAbleAbleToBakerBakerPage
AbleGET/{ableId}/ableToCharliegetAbleAbleToCharlieCharliePage
AbleDELETE/{ableId}/ableToBaker/{bakerId}deleteAbleAbleToBakerBaker
AblePUT/{ableId}/ableToBaker/{bakerId}putAbleAbleToBakerBaker
AbleDELETE/{ableId}/ableToCharlie/{charlieId}deleteAbleAbleToCharlieCharlie
AblePUT/{ableId}/ableToCharlie/{charlieId}putAbleAbleToCharlieCharlie
AblePUT/by-external-reference-code/{ableERC}/ableToBaker/{bakerERC}putAbleAbleToBakerBaker
AblePUT/by-external-reference-code/{ableERC}/ableToCharlie/{charlieERC}putAbleAbleToCharlieCharlie
CharlieGET/{charlieId}/ableToCharliegetCharlieAbleToCharlieAblePage
CharlieDELETE/{charlieId}/ableToCharlie/{ableId}deleteCharlieAbleToCharlieAble
CharliePUT/{charlieId}/ableToCharlie/{ableId}putCharlieAbleToCharlieAble
CharliePUT/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"

Capabilities

Product

Contact Us

Connect

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