feat: Add pagination and search support to /workflow/latest-versions API#934
Open
akhilpathivada wants to merge 13 commits into
Open
feat: Add pagination and search support to /workflow/latest-versions API#934akhilpathivada wants to merge 13 commits into
akhilpathivada wants to merge 13 commits into
Conversation
22047b9 to
91f0644
Compare
Signed-off-by: akhilpathivada <akhil.pathivada.21@gmail.com>
91f0644 to
b1fb587
Compare
Contributor
Author
|
@v1r3n could you please help reviewing this? |
Signed-off-by: akhilpathivada <akhil.pathivada.21@gmail.com>
Signed-off-by: akhilpathivada <akhil.pathivada.21@gmail.com>
…to V15 json_data column is text, not jsonb — the ->> operator requires an explicit ::jsonb cast. Also rename V14 migration to V15 to avoid Flyway conflict with V14__parent_workflow_id.sql from main.
Signed-off-by: akhilpathivada <akhil.pathivada.21@gmail.com>
Signed-off-by: akhilpathivada <akhil.pathivada.21@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves #781
Summary
start,size,filterFieldandfilterValuequery parameters toGET /metadata/workflow/latest-versionsfor server-side pagination and field-level searchPaginatedMetadataDAOinterface as an opt-in capability for DAOs that support database-level pagination and filteringLIMIT/OFFSET) and search (ILIKE) inPostgresMetadataDAOALLOWED_FILTER_FIELDSwhitelist inMetadataServiceImplfor input validationmeta_workflow_defto eliminate full table scans for pagination queriesWhat changed
PaginatedMetadataDAO.javasearchWorkflowDefsLatestVersions(start, size)and overloadedsearchWorkflowDefsLatestVersions(start, size, filterField, filterValue)MetadataService.javaMetadataServiceImpl.javaALLOWED_FILTER_FIELDSwhitelist; delegates toPaginatedMetadataDAOif available, otherwise falls back to in-memory pagination (no server-side filtering for non-Postgres)PostgresMetadataDAO.javaCOUNT+SELECT ... LIMIT ? OFFSET ?; search usesname ILIKE ?for name field,json_data::jsonb->>'field' ILIKE ?for othersMetadataResource.javastart/size/filterField/filterValueparams; changed return type fromList<WorkflowDef>toSearchResult<WorkflowDef>MetadataServiceTest.javaPaginatedDAO, filter with non-PaginatedDAO, empty filter, invalid filter fieldPostgresMetadataDAOTest.javaMetadataResourceTest.javastart/size/filterField/filterValuecombinations and default behaviorV15__workflow_def_latest_version_index.sqlmeta_workflow_def(name) WHERE version = latest_versionfor optimized pagination queriesAPI change
GET /metadata/workflow/latest-versions?start={start}&size={size}&filterField={field}&filterValue={value}ALLOWED_FILTER_FIELDS)Allowed filter fields: name, description, ownerEmail, version, schemaVersion, timeoutPolicy, timeoutSeconds, restartable, workflowStatusListenerEnabled
Response (changed from
List<WorkflowDef>toSearchResult<WorkflowDef>):{ "totalHits": 102, "results": [ { "name": "workflow_a", "version": 3, ... }, { "name": "workflow_b", "version": 1, ... } ] }When no parameters are provided, all latest versions are returned wrapped in SearchResult for backward compatibility.
Design decisions
1. Why an optional interface instead of modifying MetadataDAO?
Adding a new method to MetadataDAO would break all existing implementations (Redis, MySQL, etc.). The opt-in PaginatedMetadataDAO interface lets each persistence module adopt pagination at its own pace, with zero impact on others.
2. Why SearchResult instead of List?
The UI needs totalHits to render pagination controls (e.g., "Page 3 of 7"). This follows the existing pattern used by
/workflow/search.3. Why OFFSET/LIMIT over keyset pagination?
Workflow definitions typically number in the hundreds to low thousands. OFFSET/LIMIT is simpler, allows arbitrary page jumping, and performs well at this scale. Keyset pagination would add complexity (cursor management, no page jumping) with minimal benefit.
4. Why a partial index?
Without an index, Postgres performs a full table scan on every page request — even with LIMIT 15, it must read all rows to filter
WHERE version = latest_versionand sort by name. The partial indexON meta_workflow_def (name) WHERE version = latest_versionpre-filters and pre-sorts only the latest version rows, reducing page queries from full table scans to direct index lookups. The index is created usingCONCURRENTLYto avoid blocking writes on existing deployments.6. Why json_data::jsonb cast?
The
json_datacolumn is text type, notjsonb. The->>operator requiresjsonb, so an explicit::jsonbcast is needed. Thenamefield has a dedicated DB column and is queried directly without cast.7. Why no server-side filtering for non-Postgres backends?
Non-Postgres DAOs don't implement
PaginatedMetadataDAO. Rather than loading all definitions into memory for in-memory filtering (expensive), the service returns unfiltered paginated results and the UI falls back to client-side filtering. This keeps the backend lightweight and maintains backward compatibility.