Skip to content

fix(jsonapi): merge flat page/itemsPerPage params with bracket filter#8193

Merged
soyuka merged 1 commit into
api-platform:4.3from
soyuka:fix/jsonapi-flat-page-with-filter
May 22, 2026
Merged

fix(jsonapi): merge flat page/itemsPerPage params with bracket filter#8193
soyuka merged 1 commit into
api-platform:4.3from
soyuka:fix/jsonapi-flat-page-with-filter

Conversation

@soyuka
Copy link
Copy Markdown
Member

@soyuka soyuka commented May 21, 2026

Summary

When a JSON:API request combines a bracket-form filter with flat pagination
params (e.g. ?filter[name]=foo&page=2), the flat page was silently dropped
and the collection always returned page 1, while pagination links still
advertised the requested page.

Root cause

Symfony\JsonApi\State\JsonApiProvider only merged page[...] (array form)
into _api_filters. With a scalar page=2 plus a filter[...] array, the
partial _api_filters set by the provider suppressed ReadProvider's
fallback to RequestParser::parseRequestParams(), so Pagination::getPage()
never saw the page param and returned its default of 1.

Fix

Pass through scalar page, itemsPerPage, pagination, partial query
params when they are not arrays and not already populated by the bracket
form (bracket values take precedence).

Test plan

  • Unit: JsonApiProviderTest::testProvideMergesFlatPaginationWithBracketFilter
    verifies _api_filters ends up with both the filter and the flat pagination keys.
  • Functional: JsonApiFlatPaginationTest::testFlatPageWithBracketFilterDrivesCurrentPage
    hits /dummies?filter[name]=foo&page=2 with Accept: application/vnd.api+json
    and asserts meta.currentPage === 2. The test fails without the patch
    (asserts that 1 === 2).

Fixes #7888.

Notes

The longer-term fix is to port JSON:API parameter handling to dedicated
ParameterProviders (Laravel already moved sort + sparse fieldset that way).
An RFC for that work will follow as a separate issue against main.

Symfony JsonApiProvider only merged `page[...]` bracket form into
`_api_filters`. When a request combined a bracket filter with a flat
pagination param (`?filter[name]=foo&page=2`), the scalar param was
dropped: `_api_filters` ended up with only the filter, ReadProvider
used it as-is, and Pagination defaulted to page 1. Links advertised
the requested page, masking the regression.

Pass through scalar `page`, `itemsPerPage`, `pagination`, `partial`
when they are not arrays and not already populated by the bracket
form. Pre-existing bracket values take precedence.

Refs api-platform#7888.
@soyuka soyuka merged commit 286a47e into api-platform:4.3 May 22, 2026
119 of 120 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant