A number of repositories have pull requests in place to use webimpress/http-middleware-compatibility in order to allow usage with the various iterations of the PSR-15 specification; this package provides polyfill support for the various versions.
I think we need to put a halt to this for now.
While I would really love to support all versions of the specification, it’s simply non-trivial. For those who are not aware of the history of the specification, the following is a summary of the various versions:
- The 0.2.0 version of the http-interop/http-middleware package, which we followed for initial releases of Expressive, defined the namespace
Interop\Http\Middlewarewith the interfaces
DelegateInterface, each defining the method
- The 0.4.1 version of the http-interop/http-middleware package, supported by the 2.0 releases of Expressive, defined the
Interop\Http\ServerMiddlewarenamespace, and renamed the
- The 0.5.0 version of the http-interop/http-middleware package renamed the namespace to
RequestHandlerInterface, and, futher, renamed the delegate’s
- That package was then split into two, http-interop/http-server-handler and http-interop/http-server-middleware; the two combined provide the
- Assuming no more changes occur and PSR-15 is accepted with the current architecture, we will have two new packages, psr/http-server-handler and psr/http-server-middleware, using the namespace
We run into a few problems trying to support the various versions.
First, the new http-interop packages (http-server-handler and http-server-middleware) declare themselves as conflicting with http-interop/http-middleware versions >= 0.5.0. This is okay , as the two packages combined declare the same namespace and interfaces. You require one or the other. For our purposes, we’d likely include http-interop/http-server-middleware, as that package has a requirement on http-server-handler as well.
Second, we cannot support each of the previous two versions of http-interop/http-middleware (0.4.1 and 0.2.0) simultaneously, as they are the same package; we can support one or the other UNLESS we define alternative interface definitions for the version not installed.
Third, the change in interface name from
RequestHandlerInterface makes defining middleware within Stratigility and Expressive that supports multiple versions impossible, as it’s impossible to create a
process() method that will comply with any version; it must comply with a single version at a time.
Fourth, middleware authors not only need to select the interface version they plan to target, but potentially also update any calls to the delegate/request handler. If they were targeting the
DelegateInterface previously, and now target the
RequestHandlerInterface, they also must update calls to
process() within their own code to
What webimpress/http-middleware-compatibility tried to do was:
- pin a project to the http-interop/http-middleware version already in use, or, if on a new install, prompt the user for the version to use.
- adapt the various interfaces by providing polyfills and providing alternative interfaces that extend those from multiple versions
- provide a constant that references the appropriate delegate/request handler method name for use when calls to the delegate are needed
This worked fine… until the interfaces were split into two packages. At that point, the logic for choosing the package broke, as previously, you could just indicate the version to use, and now it would need to prompt for the package as well.
At this point, I wish we hadn’t updated Stratigility to use the compat package, as it’s causing more headaches than it should (in particular, developers are not aware what the various versions mean, nor that Expressive does not support the most recent versions at all); we should have just pinned to the 0.4.1 series of http-middleware and left it at that.
My inclination going forwards is that we create alpha or beta MAJOR releases that reference the new packages across any repository that currently implements or typehints against the interfaces, to allow developers to start testing against the latest spec revision. Then, when PSR-15 is approved, we do a new alpha or beta pinning to the final release, and the next MAJOR version supports PSR-15 only. In the meantime, we also start writing tools to migrate existing code as follows:
- Update middleware to implement the new interface(s)
- Update middleware delegation to use the new
This approach would also be used here in zend-mvc for the
So, in sum, my proposal for each affected repository is:
- Either create a new branch for the new major version, or mark the
developbranch as targeting the next major version (update the
- Have that branch pin to http-interop/http-server-middleware
- Update the minimum PHP version to 7.1 (per our next major release milestone announcement)
- Update affected code:
- Update any
MiddlewareInterfaceis imported from the correct namespace.
- Ensure any middleware
- Ensure any calls to the delegate call
- Update any
DelegateInterfaceimplementations (should only affect zend-stratigility and zend-expressive):
RequestHandlerInterfaceinstead, and ensure that class is correctly imported.
- Rename the
- Update any
- Create tooling for updating existing
MiddlewareInterfaceimplementations targeting http-interop 0.4.1 to the latest specification version.