dotCMS / dotCMS/core

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

Open
#35,136 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

dotCMS: New Edit Contentlet stale Team : Falcon Type : Task
Dominant language
Java
Stars
970
Forks
486
Avg merge
3d 33m
Merged PRs (30d)
170

Description

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

  • Backend endpoint: ContentResource.javaPOST /search (/api/v1/content/search)
  • Request DTO: ContentSearchForm.java — add relationshipContext field
  • Response DTO: SearchView.java — add pagination metadata
  • Frontend service: core-web/.../dot-select-existing-content/store/existing-content.service.ts
  • Frontend store: core-web/.../dot-select-existing-content/store/existing-content.store.ts
  • Related PR: #35134 (current frontend-only workaround using 2 requests)
  • Related issue: #32792 (original cardinality constraint issue)

Proposed Priority

Priority 3 - Average

Proposed Objective

Core Features

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with ContentResource.java and ContentSearchForm.java for the POST /search entry point and request shape, then read SearchView.java for the response. Trace the ExistingContentService and ExistingContentStore files to understand the current two-request flow. Done means pagination metadata, optional relationshipContext and relationParentIds work as specified while the frontend uses one paginated request and preserves backward compatibility.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, typescript
Domain
api, backend, frontend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.