Using nestedFields to Query Related Entries

Liferay 7.4 U69+/GA69+

The nestedFields parameter causes Liferay to return multiple levels of related object entries in a single GET request. Pass the nestedFields parameter with the relationship names to include in the query, separating each relationship with a comma: nestedFields=[firstObjectRelationship],[secondObjectRelationship]. If the relationships span multiple levels, set the nestedFieldsDepth parameter to the depth you need. You can include up to five levels (e.g., nestedFieldsDepth=5).

tip

The nestedFields parameter optimizes your request by retrieving entries with related entries that would otherwise require multiple requests. To return only the related entries, Liferay provides dedicated relationship APIs. See Using Relationship REST APIs for an introduction.

To proceed, set up a new Liferay 7.4 instance and prepare the provided tutorial code. Then run the scripts to create related entries and query them using the nestedFields parameter.

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 and relate three object definitions.

  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 text field to each object draft.

    Label Field Name Type Required
    Name name Text
  4. Define the following relationships.

    For Able:

    Label Relationship Name Type Object
    Able to Baker ableToBaker One to Many Baker

    For Baker:

    Label Relationship Name Type Object
    Baker to Charlie bakerToCharlie One to Many Charlie

    For Charlie:

    Label Relationship Name Type Object
    Charlie to Able charlieToAble Many to Many Able
  5. Publish each object.

Once published, you can access each object via Headless APIs.

Preparing the Sample Code

Run the commands below 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-w4s7.zip -O
unzip liferay-w4s7.zip

The ZIP provides shell scripts that run cURL commands for creating, relating, and querying object entries using REST APIs. This includes two GET commands for querying related entries.

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.

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

    cd liferay-w4s7/curl
    
  2. Execute Able_POST_ToCompany to create Able entries.

    ./Able_POST_ToCompany.sh
    

    Copy the first entry’s ID for use with the following POST command.

    {
      ...
      "externalReferenceCode" : "able-one",
      "id" : 47512,
      ...
      "name" : "Able 1"
    }
    
    {
      ...
      "externalReferenceCode" : "able-two",
      "id" : 47514,
      ...
      "name" : "Able 2"
    }
    
    {
      ...
      "externalReferenceCode" : "able-three",
      "id" : 47516,
      ...
      "name" : "Able 3"
    }
    
  3. Execute Baker_POST_ToCompany using the ID for able-one as a parameter.

    ./Baker_POST_ToCompany.sh [ableId]
    

    This creates three Baker entries and relates them to the specified Able entry using the ableToBaker relationship.

    Each Baker entry has three ableToBaker relationship fields: ableToBakerERC, r_ableToBaker_c_ableId, and r_ableToBaker_c_ableERC.

    {
      ...
      "externalReferenceCode" : "baker-one",
      "id" : 47518,
      ...
      "name" : "Baker 1",
      "ableToBakerERC" : "able-one",
      "r_ableToBaker_c_ableId" : 47512,
      "r_ableToBaker_c_ableERC" : "able-one"
    }
    
    {
      ...
      "externalReferenceCode" : "baker-two",
      "id" : 47520,
      ...
      "name" : "Baker 2",
      "ableToBakerERC" : "able-one",
      "r_ableToBaker_c_ableId" : 47512,
      "r_ableToBaker_c_ableERC" : "able-one"
    }
    
    {
      ...
      "externalReferenceCode" : "baker-three",
      "id" : 47522,
      ...
      "name" : "Baker 3",
      "ableToBakerERC" : "able-one",
      "r_ableToBaker_c_ableId" : 47512,
      "r_ableToBaker_c_ableERC" : "able-one"
    }
    

    Copy the first Baker entry ID for use with the following POST command.

  4. Execute Charlie_POST_ToCompany using the ID for baker-one as a parameter.

    ./Charlie_POST_ToCompany.sh [bakerId]
    

    This creates three Charlie entries and relates them to the specified Baker entry using the bakerToCharlie relationship.

    {
      ...
      "externalReferenceCode" : "charlie-one",
      "id" : 47524,
      ...
      "r_bakerToCharlie_c_bakerERC" : "baker-one",
      "bakerToCharlieERC" : "baker-one",
      "name" : "Charlie 1",
      "r_bakerToCharlie_c_bakerId" : 47518
    }
    
    {
      ...
      "externalReferenceCode" : "charlie-two",
      "id" : 47526,
      ...
      "r_bakerToCharlie_c_bakerERC" : "baker-one",
      "bakerToCharlieERC" : "baker-one",
      "name" : "Charlie 2",
      "r_bakerToCharlie_c_bakerId" : 47518
    }
    
    {
      ...
      "externalReferenceCode" : "charlie-three",
      "id" : 47528,
      ...
      "r_bakerToCharlie_c_bakerERC" : "baker-one",
      "bakerToCharlieERC" : "baker-one",
      "name" : "Charlie 3",
      "r_bakerToCharlie_c_bakerId" : 47518
    }
    

    You now have three Charlie entries related to a Baker entry that is itself related to an Able entry. However, if you query a Charlie entry using a basic GET request, the response only includes details for the Charlie entry. It does not include details for the related Baker or Able entries. To return details for these entries, you must use the nestedFields and nestedFieldsDepth parameters.

    Copy the first entry’s ID for use with the following GET command.

  5. Execute Charlie_GET_ById using a Charlie entry ID as a parameter.

    ./Charlie_GET_ById.sh [charlieId]
    

    This GET request calls an o/c/charlies endpoint with the nestedFields and nestedFieldsDepth parameters.

curl \
	"http://localhost:8080/o/c/charlies/${1}/?nestedFields=ableToBaker,bakerToCharlie&nestedFieldsDepth=2" \
	--user "test@liferay.com:learn"

nestedFields: Determines the relationship(s) to include in the query (ableToBaker,bakerToCharlie).

nestedFieldsDepth: Determines the depth of entries to include (2).

This command returns all three levels of related objects (i.e., Charlie, Baker, and Able).

{
  ...
  "externalReferenceCode" : "charlie-one",
  "id" : 47524,
  ...
  "r_bakerToCharlie_c_baker" : {
    ...
    "externalReferenceCode" : "baker-one",
    "id" : 47518,
    ...
    "r_ableToBaker_c_able" : {
      ...
      "externalReferenceCode" : "able-one",
      "id" : 47512,
      ...
      "name" : "Able 1"
    },
    "bakerToCharlie" : [ {
      ...
      "externalReferenceCode" : "charlie-one",
      "id" : 47524,
      ...
      "r_bakerToCharlie_c_bakerERC" : "baker-one",
      "bakerToCharlieERC" : "baker-one",
      "name" : "Charlie 1",
      "r_bakerToCharlie_c_bakerId" : 47518
    }, {
      ...
      "externalReferenceCode" : "charlie-two",
      "id" : 47526,
      ...
      "r_bakerToCharlie_c_bakerERC" : "baker-one",
      "bakerToCharlieERC" : "baker-one",
      "name" : "Charlie 2",
      "r_bakerToCharlie_c_bakerId" : 47518
    }, {
      ...
      "externalReferenceCode" : "charlie-three",
      "id" : 47528,
      ...
      "r_bakerToCharlie_c_bakerERC" : "baker-one",
      "bakerToCharlieERC" : "baker-one",
      "name" : "Charlie 3",
      "r_bakerToCharlie_c_bakerId" : 47518
    } ],
    "name" : "Baker 1",
    "ableToBaker" : {
      ...
      "externalReferenceCode" : "able-one",
      "id" : 47512,
      ...
      "name" : "Able 1"
    },
    "r_ableToBaker_c_ableId" : 47512,
    "r_ableToBaker_c_ableERC" : "able-one"
  },
  "r_bakerToCharlie_c_bakerERC" : "baker-one",
  "bakerToCharlie" : {
    ...
    "externalReferenceCode" : "baker-one",
    "id" : 47518,
    ...
    "r_ableToBaker_c_able" : {
      ...
      "externalReferenceCode" : "able-one",
      "id" : 47512,
      ...
      "name" : "Able 1"
    },
    "bakerToCharlie" : [ {
      ...
      "externalReferenceCode" : "charlie-one",
      "id" : 47524,
      ...
      "r_bakerToCharlie_c_bakerERC" : "baker-one",
      "bakerToCharlieERC" : "baker-one",
      "name" : "Charlie 1",
      "r_bakerToCharlie_c_bakerId" : 47518
    }, {
      ...
      "externalReferenceCode" : "charlie-two",
      "id" : 47526,
      ...
      "r_bakerToCharlie_c_bakerERC" : "baker-one",
      "bakerToCharlieERC" : "baker-one",
      "name" : "Charlie 2",
      "r_bakerToCharlie_c_bakerId" : 47518
    }, {
      ...
      "externalReferenceCode" : "charlie-three",
      "id" : 47528,
      ...
      "r_bakerToCharlie_c_bakerERC" : "baker-one",
      "bakerToCharlieERC" : "baker-one",
      "name" : "Charlie 3",
      "r_bakerToCharlie_c_bakerId" : 47518
    } ],
    "name" : "Baker 1",
    "ableToBaker" : {
      ...
      "externalReferenceCode" : "able-one",
      "id" : 47512,
      ...
      "name" : "Able 1"
    },
    "r_ableToBaker_c_ableId" : 47512,
    "r_ableToBaker_c_ableERC" : "able-one"
  },
  "name" : "Charlie 1",
  "r_bakerToCharlie_c_bakerId" : 47518
}
  1. Execute Charlie_PUT_CharlieToAble_ByExternalReferenceCode with these ERCs.

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

    This relates all three Charlie entries directly with the specified able-one entry using the charlieToAble relationship.

  2. Execute Able_GET_ByExternalReferenceCode with the Able entry’s ERC.

    ./Able_GET_ByExternalReferenceCode.sh able-one
    

    This GET request calls an o/c/ables endpoint with the nestedFields parameter.

curl \
	"http://localhost:8080/o/c/ables/by-external-reference-code/${1}?nestedFields=charlieToAble" \
	--user "test@liferay.com:learn"

nestedFields: Determines the relationship(s) to include in the query (charlieToAble).

This command returns details for able-one along with all details for the three related Charlie entries.

{
  ...
  "externalReferenceCode" : "able-one",
  "id" : 47512,
  ...
  "charlieToAble" : [ {
    ...
    "externalReferenceCode" : "charlie-one",
    "id" : 47524,
    ...
    "r_bakerToCharlie_c_bakerERC" : "baker-one",
    "bakerToCharlieERC" : "baker-one",
    "name" : "Charlie 1",
    "r_bakerToCharlie_c_bakerId" : 47518
  }, {
    ...
    "externalReferenceCode" : "charlie-two",
    "id" : 47526,
    ...
    "r_bakerToCharlie_c_bakerERC" : "baker-one",
    "bakerToCharlieERC" : "baker-one",
    "name" : "Charlie 2",
    "r_bakerToCharlie_c_bakerId" : 47518
  }, {
    ...
    "externalReferenceCode" : "charlie-three",
    "id" : 47528,
    ...
    "r_bakerToCharlie_c_bakerERC" : "baker-one",
    "bakerToCharlieERC" : "baker-one",
    "name" : "Charlie 3",
    "r_bakerToCharlie_c_bakerId" : 47518
  } ],
  "name" : "Able 1"
}

Charlie_GET_ById.sh

curl \
	"http://localhost:8080/o/c/charlies/${1}/?nestedFields=ableToBaker,bakerToCharlie&nestedFieldsDepth=2" \
	--user "test@liferay.com:learn"

Able_GET_ByExternalReferenceCode.sh

curl \
	"http://localhost:8080/o/c/ables/by-external-reference-code/${1}?nestedFields=charlieToAble" \
	--user "test@liferay.com:learn"

Ask

Capabilities

Product

DXP

Contact Us

Connect

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