slimphp / Slim-Http

A set of PSR-7 object decorators providing useful convenience methods

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Discussion] Should we use an existing PSR-7 Implementation?

l0gicgate opened this issue · comments

We have been going back and forth a lot on PSR-7 Compliance and some issues that are related to our current implementation of PSR-7.

I believe that we should decorate an existing implementation of PSR-7 instead of implementing our own. I would like all contributors to vote on this so we can move forward with some of the current issues.

This repo will essentially become a decorated implementation of an existing PSR-7 implementation.

There are 2 implementations that come to mind:

  • Nyholm/psr7 - This is the fastest, strictest and most lightweight implementation at the moment
  • Guzzle/psr7 - This is the implementation used by the Guzzle Client. It is not as strict but adds some nice functionality for Streams and file handling. It is the second fastest implementation but is a bit bulkier
  • zend-diactoros - This is the Zend implementation. It is the slowest implementation of the 3.

I'm in favor of dropping our PSR-7 Implementation altogether and creating a PSR-7 Decorator repo which will work with any PSR-7 implementation (Nyholm, Guzzle, Diactoros).

Vote Count

  • Nyholm/psr7 - 1 in favor
  • Guzzle/psr7 - 2 in favor
  • Zend Diactoros - 0 in favor
  • Keep current implementation - 1 in favor
  • Transform this into a PSR-7 Decorator Repo - 5 in favor

Edit
The more we talk about this, the more this thread is heading towards not including any PSR-7 implementation with Slim/Slim and have the user pass in PSR-7 objects of their choice into App::run($req, $res). Slim-Http could be transformed into a Slim-Psr7-Decorator which will work with any PSR-7 implementation. Objects passed into App::run() will be decorated by default with our decorators, an option which could be turned off in App settings.

Nyholm/psr7


I do not see any benefit of using an implementation, I'd rather implement a decorator in Slim/Slim on the PSR7 interface and drop any specific implementation.

I want to vote for Nyholm/Psr7 as it is the most to spec and the least code. It does have many benefits for being small and fits and will be included with slim to minimize what previously exists, but it is so small in usage it worries for me for potential future maitence. Guzzle/Psr7 on the other hand has wide backing and is used by so many people and is a standard used for the guzzle client and is just used so much for open source applications.

For future usage and protection of slim and not needing to maintain potentially another repo as much and wide usage I personally vote towards guzzle/psr7

--
Or just agree to keep own implementation.

I've already started using Guzzle's PSR-7 implementation in cases where Slim's was used previously, simply because it handles some extremely common pitfalls that occur with the PSR-7 implementation (namely that it tends to create http://url:80, https://url:443, etc. when some browsers don't support this for whatever reason). It's a more "real-world" implementation of the PSR than the stricter, less featured Slim version is.

I'd strongly recommend its use.

I do not see any benefit of using an implementation, I'd rather implement a decorator in Slim/Slim on the PSR7 interface and drop any specific implementation.

Good argument for the slim/slim package. We would have to ship something in the Skeleton though.

I'd rather decorate the ServerRequestInterface instead of any particular implementation, as outlined by @akrabat in this gist https://gist.github.com/akrabat/807ccfbef25baafe646ba170ac2277fd

Of course, some implementation has to be chosen as default. In my case I'd rather go for nyholm/psr7 (but this should not be difficult to change, for instance, by swapping a middleware).

Edit: Also of note, I think this course of action might not even merit a separate library.

@dominikzogg added Zend Diactoros. Can you specify some positives so I can add to description?

I quite like the idea that Slim-Http decorates a concrete implementation and Slim itself can use any PSR-7 implementation that the user wishes to use.

We get new questions though, such as can we rely on PSR-17 factories alone or do we need some of our own code to ensure that the ServerRequest is complete for use by Slim itself? I'm sure we'll come across more too.

@l0gicgate it's build for the same purpose (microframework) it's also used for symfony using PSR7 which means tons of testers and @akrabat is also zendframework maintainer which could help if we got good inputs for improvement

Via slack
geggleto [4:25 PM]
I also dislike the guzzle stuff

it changes versions weirdly (I feel)
i haven’t looked at how stable their psr-7 lib is
My suggestion would be to in traditional slim fashion; not care
we can build everything in the framework around the PSR-7 interface
and then keep the core agnostic
and in the skeleton project include a PSR-7 lib
those advanced users will just use whatever lib they want anyway
just like what we’re doing with the container

Sorry - I'm not a slimphp contributor but a user, hope it's OK if I put in my 2cents. I'm the lead developer of TYPO3 - a PHP-based CMS building upon PSR-7 and PSR-15 (and our own implementations, but currently bundled) and we face similar issues.

For my customer projects we use SlimPHP to integrate into our TYPO3 websites as lightweight REST APIs - and it works like a charm - really cool. Thanks for your work with Slim3! But now I have 2 PSR-7 implementations in one PHP project ;) - completely unnecessary IMHO. FIGs goal was to have the implementation interchangeable - so how about having factories taking care of choosing the actual implementation, a decorator would be just perfect for Slim's case. So the dev could - depending on the composite project - use the PSR-7 implementation that suits him/her.

Sry for jumping in here - a bit unrelated maybe - I feel unexperienced on how to achieve that, but would be a huge success.

Thanks for your input @bmack - user opinion is very much appreciated!

With slim's philosophy, I think that Nyholm/psr7 is a good choice, the implementation is very simple. But what i'm afraid of is that all the classes are final, they should be open for extension.

@candrianarijaona beeing extendable meaning less stable, decorators fixes the extend problem very well

Hi, I'm the developer of BitFrame PHP. I took some inspiration from Slim while developing BitFrame so it feels right to give some suggestions. The way I tackled the issue was to create a factory class where you could use HttpMessageFactory::createResponse() method to create a Response object based on default libraries (at the moment Diactoros and Guzzle), or let the developer specify his own Response library by using HttpMessageFactory:: setResponseFactory().

The idea was to allow people who want to work with defaults to just "install-and-go" and people who want to customize, the ability to set their own implementation. Hope that helps in some way.

So I put an example repository together to show how I would do things. Since things would be PSR-7 implementation agnostic, the end user would need to pass in PSR-7 factories to our DecoratedFactory.

See this demo Slim PSR-7 Decorator Repo. Note that this demo repo only includes decorator for the ResponseInterface. Obviously the real Slim repo would include decorators for RequestInterface, ServerRequestInterface, StreamInterface, etc..

The one problem we still face though is if we put Slim::App in charge of instantiating the ServerRequestInterface and ResponseInterface or do we simply have the user pass in an instantiation of it when they call App::run()

class App {
...
    public function run(ServerRequestInterface $request, ResponseInterface $response)
    {
        ...
    }
}

If Slim::App stays in charge of the instantiation as seen here https://github.com/slimphp/Slim/blob/4.x/Slim/App.php#L423

Then we would need to create a custom interface like ServerRequestCreatorInterface included in the Nyholm/psr7-server repo that the end user will have to implement to get up and running which would call their PSR-7 implementation's method to create a ServerRequestInterface from globals like:

I like nyholm.

but about the spawning and so on, folks, please have a look at using psr-17, which deals with the factories

Im sorry, but I'm not sure why the lack of an interface that's specific to drawing data from superglobals would make it unsuitable for use in slim.

ServerRequestFactoryInterface does provide createServerRequest, which returns a suitable Server RequestInterface implementation, the only part that isn't covered is how you convert the superglobals to $serverParams and that is a good thing, as it allows people to fill them no matter in what context this is run (as super globals aren't always a choice)

My point is simply that using the factory still requires additional work that needs to be opt-in. As such, Slim 4 can't just accept the factory, it must also have a way to accept a fully instantiated ServerRequst.

At which point what benefit does the PSR-17 factory give us?

The PSR-17 factory for Response is far more useful to Slim.

What's the point of following a standard in one place but not the other?

I'm just observing what works and what doesn't and what Slim would need to do. Someone needs to convert the superglobals to serverparams and every PSR-7 implementation has a way to do this. Logically, we should leverage that code, but it's not been standardardised.

@ppetermann please read my last comment. It goes over all that.

I would not depend on any PSR-7 implementation. I am personally using nyholm one, but it would be great if people could make their own choice.

Looking for input from @slimphp/maintainers …

My current thoughts:

  1. Moving the Slim-Http specific features to a decorator component that can wrap any PSR-7 implementation is desirable.

  2. I'm not sure we should ditch our own PSR-7 implementation.

My thoughts are still the same.

Just decorate any PSR7 implementation, and let's give the freedom to the user to implement the one ze prefers.

The default one shipped with slim may be slim-http, but is not a big deal once we explain how to swap it.

I did a similar thing for moon

As per our Slack discussion, this repo is going to become a decoration repository. Follow further discussion in the #67. As for now Slim-Http PSR-7 Implementation has been moved to Slim-Psr7, once Slim 4 is released we may put some effort into maintaining our own PSR-7 Implementation.