Skip to content

Enhance /api/v1/content/search with server-side pagination and relationParentIds for relationship constraints #35136

@oidacra

Description

@oidacra

Problem Statement

The "Select Existing Content" dialog in the Relationship Field currently makes 2 requests without server-side pagination, which doesn't scale with large datasets (e.g., 5k+ contentlets). Additionally, a second request is needed to determine which child contentlets are already "taken" by other parents in ONE_TO_ONE and ONE_TO_MANY relationships.

Current Behavior

  1. POST /api/v1/content/search returns all contentlets at once — the dialog does not use server-side pagination
  2. Response has pagination: null — no pagination metadata returned
  3. A separate request to /api/content/_search is needed to find which children are already related to other parents (workaround implemented in PR #32792 Relationship Field: disable already-related items in dialog #35134)

Proposed Solution

1. Server-side pagination in the response

The endpoint already accepts page and perPage in ContentSearchForm, but the response doesn't include pagination metadata. Return pagination info in the response:

{
  "entity": {
    "jsonObjectView": { "contentlets": [...] },
    "resultsSize": 5000,
    "pagination": {
      "page": 1,
      "perPage": 50,
      "totalPages": 100
    }
  }
}

2. Relationship constraint info via relationshipContext

Accept an optional relationshipContext in the request payload:

{
  "searchableFieldsByContentType": { "contentTypeId": {} },
  "page": 1,
  "perPage": 50,
  "relationshipContext": {
    "fieldVariable": "relation",
    "parentContentType": "MAIN"
  }
}

When relationshipContext is provided, each contentlet in the response includes a relationParentIds field — an array of parent identifiers that already have this child related:

{
  "identifier": "82c25d2e-...",
  "comment": "comment 2",
  "relationParentIds": ["ccb20dddbb896bd75800a2a672515a99"]
}
  • Empty array [] → child is free, selectable
  • Array with identifiers → child is taken by those parents
  • When relationshipContext is NOT provided, relationParentIds is omitted (backward compatible)

Acceptance Criteria

  • POST /api/v1/content/search returns pagination metadata in the response when page/perPage are provided
  • ContentSearchForm accepts an optional relationshipContext object with fieldVariable and parentContentType
  • When relationshipContext is included, each contentlet in the response includes a relationParentIds string array
  • relationParentIds is [] when the child has no parent in that relationship
  • relationParentIds contains parent identifiers when the child is already related
  • When relationshipContext is NOT provided, the response remains unchanged (backward compatible)
  • Frontend ExistingContentService updated to send page/perPage and relationshipContext to the API
  • Frontend ExistingContentStore updated to use server-side pagination and relationParentIds instead of the separate /api/content/_search request
  • The separate constraint request (/api/content/_search for parents) can be removed from the frontend

Technical Context

Proposed Priority

Priority 3 - Average

Proposed Objective

Core Features

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    Status

    Future

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions