refactor: use provider/processor instead of event listeners #5657
+5,220
−610
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
tldr: This patch introduces providers and processors as a replacement for Symfony listeners.
API Platform standalone
The idea behind that is to make API Platform work without using Symfony's HttpKernel. This means that to use API Platform, all you need to do is:
This allows:
Impact on DX and BC-layer
Let me explain this last part. Today API Platform relies on the HttpKernel and hooks various event listeners do to work. While doing this, it alters the way Symfony itself works by adding (or mutating) Request::$attributes. The most notable change compared to a standard Symfony is that, when you're router goes through API Platform your controller can return
mixed
instead of aResponse
:core/src/Action/PlaceholderAction.php
Lines 21 to 32 in 6007550
Indeed, API Platform will intercept the
mixed
data and create theResponse
for you. This IMO is not so good especially when using API Platform programmatically.Because we rely on event listeners, we need to make choices for the framework and for example we choose to call Symfony's security before validating the user input. This lead (and still leads) to issues (#5756) as you may want stuff to be made differently. Even within Symfony, http kernel listeners priorities are NOT part of the backward compatibility layer, and therefore everyone will tell you to avoid using listeners if possible, especially avoid relying on vendor listeners.
State providers and processor will help a lot with that. For example in API platform 3.1 we'd have this for our security:
core/src/Symfony/Bundle/Resources/config/security.xml
Lines 23 to 28 in 6007550
(note that the logic is currently duplicated to work with graphql)
But in API Platform 3.2 we declare 3 different services that just decorate the correct service where it needs to hook security (
read
,deserialize
,validate
):core/src/Symfony/Bundle/Resources/config/security.xml
Lines 19 to 34 in 5138850
There is a better compatibility layer, you can also do this yourself if you have custom needs without needing an event listener or to merge a new feature. This is, in my opinion, way better to extend API Platform and be less "constraint" then we previously where on every aspect!
This is the result of almost 6 months of code and years of discussions with the core team, many users at conferences or at work so thanks to everyone!