Enhance /api/v1/content/search with server-side pagination and relationParentIds for relationship constraints
Nobody has claimed this yet.
- 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
POST /api/v1/content/searchreturns all contentlets at once — the dialog does not use server-side pagination- Response has
pagination: null— no pagination metadata returned - A separate request to
/api/content/_searchis 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
relationshipContextis NOT provided,relationParentIdsis omitted (backward compatible)
Acceptance Criteria
-
POST /api/v1/content/searchreturns pagination metadata in the response whenpage/perPageare provided -
ContentSearchFormaccepts an optionalrelationshipContextobject withfieldVariableandparentContentType - When
relationshipContextis included, each contentlet in the response includes arelationParentIdsstring array -
relationParentIdsis[]when the child has no parent in that relationship -
relationParentIdscontains parent identifiers when the child is already related - When
relationshipContextis NOT provided, the response remains unchanged (backward compatible) - Frontend
ExistingContentServiceupdated to sendpage/perPageandrelationshipContextto the API - Frontend
ExistingContentStoreupdated to use server-side pagination andrelationParentIdsinstead of the separate/api/content/_searchrequest - The separate constraint request (
/api/content/_searchfor parents) can be removed from the frontend
Technical Context
- Backend endpoint:
ContentResource.java→POST /search(/api/v1/content/search) - Request DTO:
ContentSearchForm.java— addrelationshipContextfield - 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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