Skip to content

feat: elasticsearch - #8430

Open
laryjulien wants to merge 7 commits into
api-platform:mainfrom
laryjulien:feat/es
Open

feat: elasticsearch#8430
laryjulien wants to merge 7 commits into
api-platform:mainfrom
laryjulien:feat/es

Conversation

@laryjulien

Copy link
Copy Markdown
Contributor
Q A
Branch? main
Tickets
License MIT
Doc PR api-platform/docs#...

laryjulien and others added 7 commits July 29, 2026 09:21
symfony/mcp-bundle dev-main now requires mcp/sdk ^0.7 which conflicted
with the root ^0.6 constraint, making the project impossible to install.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
tests/Fixtures/app/config/reference.php was removed with the Symfony 8
support commit but its excludePaths entry remained, breaking every local
PHPStan run.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Removes the legacy elasticsearch/elasticsearch v7 client (Elasticsearch\Client)
from the providers, the client factory compiler pass and the bundle
configuration. Elasticsearch 7 is end-of-life; the component now requires
elasticsearch/elasticsearch ^8.4 || ^9.0 (OpenSearch support is unchanged).

The CI matrix entry running against Elasticsearch 7.17 now runs against 8.4
with the lowest supported client version.

BREAKING CHANGE: the Elasticsearch state providers no longer accept an
Elasticsearch\Client (v7) instance.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds an ES|QL-based collection provider as an alternative to the classic
_search Query DSL, selectable globally (api_platform.elasticsearch.query_language)
or per operation (queryLanguage state option):

- EsqlQuery: injection-safe query builder using named value (?p) and
  identifier (??f) parameters, with the full-text conditions always
  compiled into the first WHERE command after FROM
- parameter filters aligned with the Doctrine bridges: ExactFilter,
  MatchFilter (full-text), ComparisonFilter (gt/gte/lt/lte/ne/between)
  and SortFilter
- extension chain mirroring the Doctrine architecture, including a
  ParameterExtension bridging QueryParameter to filters (with an explicit
  error for "nested" fields, unsupported by ES|QL) and a PaginationExtension
  implemented as a result extension
- partial pagination only (ES|QL has no offset and no total hit count):
  the paginator fetches LIMIT n+1 rows and exposes hasNextPage()
- handleLinks state option for subresource support
- items keep using the document GET API whatever the query language

Requires Elasticsearch >= 8.14 at runtime; not available with OpenSearch
(rejected at configuration time). The default query language remains "dsl".

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Paginator: expanding dotted columns no longer crashes on text multi-fields
  (e.g. "title" + "title.keyword"); the scalar parent wins and sub-field
  columns are skipped. Denormalized documents are now memoized like in the
  Query DSL paginator.
- PaginationExtension: requesting "page" > 1 is rejected with a 400 instead
  of silently returning the first page; the pagination service is asserted
  in getResult().
- CollectionProvider: the handleLinks state option now accepts
  LinksHandlerInterface instances and throws on unresolvable values instead
  of silently skipping them (the WHERE constraint could be dropped).
- Both ES|QL executors verify that the client provides the esql() endpoint
  (elasticsearch/elasticsearch >= 8.11) before querying.
- The ES|QL services are only registered when the Elasticsearch client is
  used: lint:container passed again for OpenSearch users, and a per-operation
  "queryLanguage: esql" with OpenSearch now fails at metadata build time
  with an explicit error. GraphQL operations always use the Query DSL
  providers (the ES|QL paginator is partial-pagination only).
- The opensearch/esql configuration validation no longer runs when
  Elasticsearch support is disabled.
- New Elasticsearch tests use PHPUnit stubs instead of prophesize
  (CONTRIBUTING.md).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- require elasticsearch/elasticsearch >= 8.11 (root and component): the
  esql() endpoint does not exist before, and older elastic/transport
  releases pin psr/http-message ^1.0 which conflicts with
  opensearch-project/opensearch-php ^2.5 under --prefer-lowest
- CI: replace the broken prefer-lowest Elasticsearch matrix entry (no lock
  file, so the partial update installed the v9 client against the 8.4
  server) with an explicit v8 client pin
- do not implement SortFilterInterface in the ES|QL SortFilter yet: the
  component jobs may resolve api-platform/metadata to a 4.x release that
  predates the marker, and GraphQL operations never use ES|QL filters
- allow mcp/sdk 0.7 in the mcp component, same conflict as the root one
- drop the stale PartialDenormalizationException PHPStan ignore pattern,
  unmatched since a dependency bump

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rch)

- Laravel: symfony/mcp-bundle dev-main added a required MiddlewareFactory
  argument to McpController; pass one with its defaults (SDK DNS-rebinding
  protection kept)
- Elasticsearch component: conflict with psr/http-factory < 1.0.2 so a
  --prefer-lowest install can coexist with opensearch-project/opensearch-php
  (psr/http-factory 1.0.0 pins psr/http-message ^1.0 while opensearch-php
  requires ^2.0, and the factory is outside the -W allowlist of the
  opensearch require)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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