api-platform/core
API Platform Core is an easy-to-use, powerful PHP library for creating hypermedia-driven REST and GraphQL APIs. Integrate it with Symfony, support JSON-LD, Hydra, OpenAPI, JSON:API, HAL, and Problem Details, and build fully featured API-first projects in minutes.
Architecture fit. api-platform/core is a metadata-driven API engine, not a controller library. You declare a class as a resource, attach operations, and the framework derives routing, serialization, validation, pagination, filters, and schema output (JSON-LD/Hydra, JSON:API, HAL, OpenAPI 3.2, Problem Details, GraphQL) from that metadata. The mental model is a state pipeline — providers read, processors write, and everything between is metadata-configured. It is a strong fit when the deliverable is "a documented, hypermedia-correct API over a domain model" and a poor fit when the deliverable is "a handful of bespoke endpoints with unusual transport semantics." The repository is a monorepo (metadata, serializer, jsonld, hydra, openapi, json-schema, state, doctrine-orm/odm, elasticsearch, graphql, laravel, symfony, mcp), and api-platform/core on its own is only the substrate — the Laravel experience is delivered by the sibling api-platform/laravel package. Treat the two as one adoption unit and evaluate them together.
Integration feasibility. Feasible, and materially more viable than it was a year ago: the 4.4 line stabilized the Laravel integration, removing its @experimental flag (the only remaining experimental surface is MCP). That is the single most important data point in this assessment — it converts Laravel from "evaluate at your own risk" to "covered by the BC promise." Two caveats. First, the changelog shows a clear maintenance asymmetry: the fix stream is dominated by fix(symfony), fix(doctrine), fix(serializer), and fix(openapi), while fix(laravel) entries are thin and infrastructural (fix(ci): link monorepo root in laravel e2e, fix(laravel): require api-platform/metadata ^4.4@alpha). Stabilized is not the same as battle-tested. Second, persistence is the open question — the Laravel adapter leans on Doctrine ORM state providers; do not assume existing Eloquent models are drop-in resources.
Technical risk. Three risks dominate, in order:
symfony/* ^7.4 || ^8.0 across all components and explicitly drops Symfony 6.4 and 7.0–7.3. Laravel ships its own pinned Symfony components. If your Laravel release does not yet carry Symfony 7.4, composer require api-platform/laravel will not resolve cleanly. Plan on 4.3.x until the matrix lines up.feat!: remove deprecated APIs scheduled for 5.0, a PropertyInfo → symfony/type-info swap, and a wholesale filter redesign (legacy SearchFilter/Boolean/Numeric/BackedEnum/OrderFilter deprecated in favor of standalone comparison/date/exists filters). A migration codemod (api:upgrade-filter) exists, but it is a Symfony command — confirm there is a Laravel equivalent before committing.Key questions.
api-platform/laravel at our target version resolve against our Laravel/Symfony component matrix?jsonapi.use_iri_as_id defaulting to true is now deprecated.api:upgrade-filter available under Laravel, and what is the 4.4 → 5.0 effort?Stack fit. Best on greenfield Laravel services where the API is the product and the domain model is stable enough to annotate. Weakest on existing Laravel apps with an established JSON contract and controller-per-endpoint conventions — the retrofit cost is contract churn, not code. Budget for PHP 8.x and a modern Laravel; treat the Symfony component floor as the binding constraint.
Migration path. Do not convert an existing API in place. Mount API Platform under a distinct prefix (/api/v2) as a parallel surface, keep the legacy controllers serving traffic, and cut over resource group by resource group behind a routing flag. This lets the OpenAPI document be the migration contract: publish it from API Platform, diff it against the existing contract, and resolve breaking differences before any client moves. Greenfield teams should skip the parallel surface and go direct, but still freeze the response format on day one.
Compatibility. Response format is the real compatibility decision, and it is irrevocable in practice. Hydra/JSON-LD gives you the most framework value (HATEOAS, discoverability) and the highest client-side cost. JSON:API is a defensible middle ground. Bare JSON with a generated OpenAPI 3.2 document is the lowest-friction choice for teams with existing clients — OpenAPI 3.2 support landing in 4.4 is a genuine win here. Also verify pagination envelope, error shape (Problem Details is the default and is not what most Laravel clients expect), and IRI-vs-ID identifier conventions.
Sequencing.
composer.lock discipline across the monorepo packages.Maintenance. The steady-state cost is upgrade management, not bug-fixing. Expect a 4.4 deprecation wave immediately followed by 5.0 removals, a filter API redesign requiring per-filter migration, and the PropertyInfo → symfony/type-info change to ripple into any custom metadata factories. Pin to exact minor versions, run the upgrade codemods in CI rather than once, and refuse to adopt @experimental surfaces (currently MCP) for anything customer-facing. The fix(laravel): require api-platform/metadata ^4.4@alpha bug is instructive: inter-package constraints inside the monorepo have broken clean installs before, so lockfiles plus a nightly composer update --dry-run are cheap insurance.
Support. No vendor, no SLA. Community channels and GitHub issues, with documentation and answer density both skewed heavily toward Symfony — expect your Laravel-specific questions to have fewer precedents. The realistic support plan is a named internal owner who reads the changelog each release and a pinned dependency update cadence, not an external escalation path.
Scaling. Genuine strengths: built-in pagination, HTTP caching with ETag/Cache-Control, and state providers that let you swap Doctrine, Elasticsearch, or custom read models without touching the resource definition. Real weaknesses: filters compile into queries you did not hand-write, so N+1 and over-fetching surface under load rather than in review; and the metadata/schema layer adds cold-start and memory overhead worth benchmarking on your target runtime. Load-test the generated collection endpoints, not a hand-written one.
Failure modes. Watch for: metadata cache corruption or stale dumped metadata on deploy (there is now explicit support for booting without a database via dumped metadata — good for prod, another cache to warm correctly in your release pipeline); content-negotiation mismatches silently returning a different format than the client expects; schema generation failing during cache warm and taking the deploy with it; and filter inputs reaching the query layer, where the changelog's recurring IRI type-confusion and denormalization fixes should be read as an active attack surface, not a settled one. Treat version upgrades as security-relevant events.
Ramp-up. A mid-level Laravel developer needs roughly two to four weeks to be productive and closer to two months to be safe with the security expression layer and custom state providers. The cost is conceptual, not syntactic: unlearning controller-per-route in favor of resource-plus-operation, and accepting that the framework owns serialization. Front-load that training on the spike, and keep at least one person fluent in the underlying Symfony components — that is the person who will debug the integration when the Laravel-specific documentation runs out.
How can I help you explore Laravel packages today?