With a slight delay, but with positive news:
… Laminas MVC would continue with
security-onlystatus until the security support for PHP 8.4 ends, which will be 31st December 2028.
With a slight delay, but with positive news:
… Laminas MVC would continue with
security-onlystatus until the security support for PHP 8.4 ends, which will be 31st December 2028.
Thanks — having 31 Dec 2028 in writing genuinely helps planning, even if
it’s not the answer everyone was hoping for.
I’d like to pick up the point raised earlier, because we’re in exactly
that situation and I don’t think the thread ever got a concrete answer.
We run a fairly large API on Laminas API Tools (so MVC underneath): 183 REST services,
~500k handwritten LOC, PHP 8.4. Auth is api-tools-oauth2/bshaffer with 6 custom grant types plus
OpenID Connect. We already maintain 14 forks of api-tools and laminas packages just to
stay on PHP 8.4 — so “just fork it” isn’t a future option for us, it’s what we do today, and
it’s not what I want to still be doing in 2029.
We’ve mapped out the alternatives (keep forking, Mezzio, incremental Symfony, full rewrite),
but every effort number we have is a guess. What I can’t find
anywhere is a real data point, so:
mezzio-hal looks like a close matchapi-tools-content-validation /api-tools-mvc-auth + ACL, and custom OAuth2 grant types actuallyIf we do go ahead, I’m happy to write up whatever we learn. There’s still no migration guide
for api-tools users, and I suspect quite a few of
us are quietly sitting on this stack.
@babuka19901990 — I’ll take #3 since it was pointed at me, and add what I can on #1 and #2.
Where I’m speaking from: at Apidemia we’ve been on Expressive/Mezzio since 2017, and we maintain Dotkernel, a headless platform built on Mezzio. The relevant piece for you is Dotkernel API — a Mezzio + Doctrine ORM application that exists to do the job api-tools did, minus the config-driven layer. It’s public, so instead of taking my word on how the api-tools concerns map, you can read a working pipeline: GitHub - dotkernel/api: A production-ready REST API application built on the Mezzio microframework and Laminas components, which implements standards like PSR-3, PSR-4, PSR-7, PSR-11 and PSR-15. · GitHub
Answering this first, because it determines the effort in #1.
| api-tools | target |
|---|---|
api-tools-hal |
mezzio/mezzio-hal |
api-tools-content-negotiation |
pipeline middleware; in Dotkernel it’s config/autoload/content-negotiation.global.php, Accept/Content-Type → application/json, application/hal+json |
ApiProblem |
mezzio/mezzio-problem-details (RFC 7807 / 9457) |
api-tools-content-validation + input filter specs |
laminas/laminas-inputfilter — unchanged, specs port as-is |
api-tools-mvc-auth + ACL |
mezzio/mezzio-authentication + mezzio-authorization-acl / -rbac |
api-tools-oauth2 (bshaffer) |
mezzio/mezzio-authentication-oauth2 → league/oauth2-server |
api-tools-rest / -rpc controllers |
PSR-15 handlers |
api-tools-versioning |
route prefix or Accept-header middleware |
Where it isn’t a clean swap:
dotkernel/dot-doctrine-metadata as a wrapper for exactly that, and it’s in maintenance mode because the reason for it went away.GrantTypeInterface / AbstractGrant — each individually small and well isolated, but the client/token/scope schema differs, so it’s also a data migration, plus key material, plus a decision about tokens in flight at cutover. And league core is OAuth2 only; OIDC needs an extension layered on top. If I were scoping this I’d spike the grants and OIDC first and estimate everything else afterwards. Endpoint conversion is boring and linear once the auth boundary works.We’ve done Apigility/api-tools → Mezzio migrations, but I’d rather not put someone else’s project figures in a public thread. What I can give you is the shape, which is where estimates usually go wrong:
AbstractResourceListener, the event manager, controller plugins and the api-tools config tree. That figure is your migration; the rest is code that moves buildings without noticing.Yes, we run this, and it stays manageable if the boundary is drawn in one place. What works:
public/index.php runs the Mezzio pipeline; the last middleware in it is a legacy bridge that hands off to Laminas\Mvc\Application and buffers the result into a PSR-7 response. Anything routed in Mezzio wins, everything else falls through untouched. The reverse — dispatching Mezzio from an MVC route — also works, but leaves you with two routers arguing over precedence.EntityManager, one connection pool. This is the concrete argument for doing the incremental move inside the ecosystem: an incremental Symfony migration gives you two containers and two service graphs for the entire duration, and that duration is measured in years.api-tools-mvc-auth. Two live auth stacks is where these projects become unmanageable.SessionPersistenceInterface that reads laminas-session’s storage so both sides see the same session. Doable, but it’s the fiddly part.)What degrades it: no forcing function. Cut over per resource with a date per resource. “We’ll migrate things as we touch them” is how you end up running both stacks in 2029, which is the outcome you said you want to avoid.
I’m not going to argue you out of evaluating Symfony — with your constraints you should. But I’d separate the question, because “will this framework exist in 2035” is the wrong thing to optimise for.
In Mezzio, the surface you depend on is PSR-7, PSR-11, PSR-15. A handler is a class with one method that takes a request and returns a response. If Mezzio vanished tomorrow, those handlers run on any other PSR-15 runner with a new config layer — days of work, not a rewrite. That’s a structural property, not a promise, and it’s the honest answer to @Jilco’s concern. ZF → Apigility → API Tools hurt precisely because the coupling was deep and config-driven; the whole point of the middleware model is that it isn’t.
On maintenance specifically: Apidemia funds work on Mezzio and the surrounding packages because our own product line sits on it — Dotkernel API shipped v7 in December with PostgreSQL, native UUID and PHP 8.5 support. That’s a commercial interest rather than a guarantee, and you should weigh it as such. But it’s a different risk profile from “volunteers ran out of time.”
Happy to go into detail on the grant-type rewrite or the legacy bridge if that’s useful. And yes to the write-up — if you document your migration, we’ll contribute the api-tools → Mezzio mapping from our side. That guide should exist and it doesn’t.