Skip to content

[Runtime] Add support for PSR-7, PSR-15 and PSR-17 #40436

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from

Conversation

Nyholm
Copy link
Member

@Nyholm Nyholm commented Mar 10, 2021

Q A
Branch? 5.x
Bug fix? no
New feature? yes
Deprecations? no
Tickets
License MIT
Doc PR

This will add a PSR runtime. The issue with PSR-7 and PSR-17 is that there is nothing covering how to create a ServerRequest from globals nor how to emit/send the response.

This PR is using two packages: nyholm/psr7-server and laminas/laminas-httphandlerrunner. Why these? The former is because it was the first one package that was trying to create a ServerRequest from globals. It might be more popular packages out now, I dont know.

The latter is a super old package (previously form zend). It is stable and does the job well.

How to use

require_once dirname(__DIR__).'/vendor/autoload_runtime.php';

return function (\Psr\Http\Message\ServerRequestInterface $request) {
    return new \Nyholm\Psr7\Response(200, [], 'PSR-7');
};
use Psr\Http\Server\RequestHandlerInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;

require_once dirname(__DIR__).'/vendor/autoload_runtime.php';

class Application implements RequestHandlerInterface {
    public function handle(ServerRequestInterface $request): ResponseInterface
    {
        return new \Nyholm\Psr7\Response(200, [], 'PSR-15');
    }
}

return function (array $context) {
    return new Application($context['APP_ENV'] ?? 'dev');
};

TODO

  • Add tests
  • Add docs
  • Add changelog

@carsonbot
Copy link

Hey!

I like what you have done here. Keep up the good work.

I think @greg0ire has recently worked with this code. Maybe they can help review this?

Cheers!

Carsonbot

@Nyholm
Copy link
Member Author

Nyholm commented Mar 11, 2021

Ah, @carsonbot I see that you are a bit confused. @greg0ire has made changes to composer.json.

@stof
Copy link
Member

stof commented Mar 11, 2021

Ah, @carsonbot I see that you are a bit confused. @greg0ire has made changes to composer.json.

but nobody outside the core team has made changes to the Runtime component yet, as only @nicolas-grekas made changes there for now 😄

@ajgarlag
Copy link
Contributor

I have tested the PsrRuntime with my proxy app using the laminas_emitter and it works.

Do you think that the ConditionalStreamiEmitter class should be added to this PR? This is the code:

use Laminas\HttpHandlerRunner\Emitter\EmitterInterface;
use Laminas\HttpHandlerRunner\Emitter\SapiEmitter;
use Laminas\HttpHandlerRunner\Emitter\SapiStreamEmitter;

class ConditionalStreamEmitter implements EmitterInterface
{
    private $sapiEmitter;
    private $sapiStreamEmitter;

    private function getSapiEmitter(): SapiEmitter
    {
        if (!isset($this->sapiEmitter)) {
            $this->sapiEmitter = new SapiEmitter();
        }

        return $this->sapiEmitter;
    }

    private function getSapiStreamEmitter(): SapiStreamEmitter
    {
        if (!isset($this->sapiStreamEmitter)) {
            $this->sapiStreamEmitter = new SapiStreamEmitter();
        }

        return $this->sapiStreamEmitter;
    }

    public function emit(ResponseInterface $response): bool
    {
        if ($response->hasHeader('Content-Disposition') || $response->hasHeader('Content-Range')) {
            return $this->getSapiStreamEmitter()->emit($response);
        }

        return $this->getSapiEmitter()->emit($response);
    }
}

@nicolas-grekas
Copy link
Member

With #40513 coming, this can now be shipped as a standalone package (or be added to https://github.com/symfony/psr-http-message-bridge)

I'm closing therefor. Thanks for pushing this forward, we have a nice road to pave :)

@Nyholm
Copy link
Member Author

Nyholm commented Mar 19, 2021

I've added this package here: https://github.com/php-runtime/psr-nyholm-laminas

I'll keep working on it with a good readme and instructions.

Nyholm added a commit that referenced this pull request Mar 19, 2021
…kas)

This PR was merged into the 5.3-dev branch.

Discussion
----------

[Runtime] make GenericRuntime ... generic

| Q             | A
| ------------- | ---
| Branch?       | 5.x
| Bug fix?      | no
| New feature?  | yes
| Deprecations? | no
| Tickets       | -
| License       | MIT
| Doc PR        | -

This PR will allow #40436 to move to https://github.com/symfony/psr-http-message-bridge
For the record, it builds on a prototype I wrote almost one year ago at https://github.com/tchwork/bootstrapper.

This PR makes the `GenericRuntime` implementation able to auto-discover runtime implementations for specific types.

It uses the autoloader for the discovery: when a closure-app requires or returns a type `Vendor\Foo`, it will use a convention and check if the class `Symfony\Runtime\Vendor\FooRuntime` exists. If yes, it will use it to resolve the corresponding type. Such runtime classes have to extend `GenericRuntime` so that they can use the protected API it provides. This requirement is aligned with the fact that the very convention proposed here is an implementation detail that works when using a `GenericRuntime` as the main runtime (This behavior can be overridden by providing explicit entries in the new `runtimes` option when booting the `GenericRuntime`.)

`SymfonyRuntime` can be used as both the main runtime or a type-specific runtime:
- when used as the main runtime, it configures the typical global-state for Symfony and has a fast codepath for Symfony types, while still being generic.
- it can also be used in another runtime as a way to resolve Symfony types (would typically be useful to #40436 for running Console apps in a PSR-based web app.)

Commits
-------

33e371e [Runtime] make GenericRuntime ... generic
weaverryan added a commit to symfony-tools/carsonbot that referenced this pull request Apr 8, 2021
…r (Nyholm)

This PR was merged into the master branch.

Discussion
----------

Ignore changes to composer.json when looking for reviewer

See symfony/symfony#40436 (comment)

Commits
-------

d5a1f45 Ignore changes to composer.json when looking for reviewer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants