Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[RFC] redesign the way flash messages work #28804

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
nicolas-grekas opened this issue Oct 10, 2018 · 15 comments
Closed

[RFC] redesign the way flash messages work #28804

nicolas-grekas opened this issue Oct 10, 2018 · 15 comments
Labels
RFC RFC = Request For Comments (proposals about features that you want to be discussed)

Comments

@nicolas-grekas
Copy link
Member

nicolas-grekas commented Oct 10, 2018

Flash messages are typically used in a POST-redirect-GET process.
Because flash messages use the session, the target GET page cannot be cached.
See e.g. symfony/demo#859 on the topic.

Using JavaScript, we can fix the issue but we need to completely redesign how flashes work:
Instead of making the POST request trigger a 302, we would make it a 200 with a <meta> redirection. Just before the meta tag, we would dump a <script> one that would put the flashes in local storage. Then the header of all pages would contain JS to read that and display them.

We could deprecate the flash bag on the session while doing so.

@nicolas-grekas nicolas-grekas added the RFC RFC = Request For Comments (proposals about features that you want to be discussed) label Oct 10, 2018
@javiereguiluz
Copy link
Member

I'm not sure about all this. In my experience, flash messages are mostly used in non-cacheable private pages, like backends, shopping carts, user profile/settings, etc.

Also, the "Post -> redirect -> GET" workflow can be easily tweaked if needed. Instead of redirecting for example to the homepage to display the flash message, forget about the homepage and redirect either to the same page (display "Your user settings have been successfully saved" above the form that edits the settings) or to a dedicated page ("Thank you for contacting us. We'll call you back soon.")

@fabpot
Copy link
Member

fabpot commented Oct 11, 2018

Flash messages are used for a LOT of things, not just for forms. We cannot deprecate the flash bag.

@stof
Copy link
Member

stof commented Oct 11, 2018

And forcing to return a fake redirect page with a meta redirection looks weird to me as well.

I think what is needed instead is clearly documenting that using flash message in the project makes pages uncacheable (due to flash messages being a private thing), and letting each project define what they want to do:

  • stop using flash messages (that's a totally valid option. I actually have very few of them in the Incenteev codebase for instance, and they tend to disappear little by little when reworking places using them). this can be done in multiple ways:
    • stop showing such feedback after saving the form
    • you could imagine having a feedback_message query parameter, which you could set when redirecting, and use in your layout to display the message (and that stays cacheable as the URL is different)
  • read flash messages in a different way (nothing forces you to read them in your Twig layout, you can have an AJAX request loading the flash messages from the server and rendering them)
  • keep using flash messages in the Twig layout, and accept the non-cacheable behavior (maybe only on some part of the app and not on all of it, as it does not need to be part of the global layout)

@nicolas-grekas
Copy link
Member Author

Thanks for the comments and ideas that's interesting. Using the session as a transport for flashes is maybe what we should reconsider. A messenger bus might be more appropriate?
The separate request is a good idea. It would need to happen on all pages on the demo app, but that's maybe fine. More ideas?

@sstok
Copy link
Contributor

sstok commented Oct 14, 2018

What about a more neutral notification interface? In the 'handler' you can use a Flash message as you do now or dispatch a message to a central server for push notifications (to name something).

Many have already implemented something similar but there is no common interface or implementation.

@nCrazed
Copy link

nCrazed commented Oct 15, 2018

Using the session as a transport for flashes is maybe what we should reconsider.

It should still be possible for cases where a JS requirement is unacceptable or just undesirable.

@sstok
Copy link
Contributor

sstok commented Oct 15, 2018

Maybe #28877 could a be valuable alternative 🤔

@dunglas
Copy link
Member

dunglas commented Oct 16, 2018

The POST-redirect-GET process as well as x-www-form-urlencoded forms are becoming legacy. The web platform has changed, web components, progressive web apps, service workers and all these new standards encourage to use JavaScript to generate forms, and a web API (REST or GraphQL) to handle them.
Modern frontend tools (React, Vue, Angular) are also designed from the ground to work this way.

We should update the documentation to explain the problem with flash bags regarding cache, but we should probably also start recommending to use JS and web APIs for forms, at least for new applications.
For new projects, there are no drawbacks to use JS + a web API for forms (search engines cannot index POST pages anyway, and accessibility is not an issue for years), but there are a lot of benefits (better UX, better performance - especially on mobile, usually easier to develop).

It's maybe a bit too early to encourage to switch all apps to SPAs or PWAs (especially because Server Side Rendering is still a bit difficult to master), but for forms, I think it's the way to go.
What I've in mind is something like I described in https://symfony.com/blog/introducing-symfony-panther-a-browser-testing-and-web-scrapping-library-for-php (still use Twig for GET pages, but use JS to handle non-safe methods).
Progressively switching to such patterns would fix this kind of issues, and is (IMO) the sense of history.

@nCrazed
Copy link

nCrazed commented Oct 17, 2018

For new projects, there are no drawbacks to use JS

Why force the change in a general purpose framework instead of providing options (via driver/transport configuration) and let developers decide what is and is not a drawback in their use case?

@dunglas
Copy link
Member

dunglas commented Oct 17, 2018

@nCrazed I'm not telling to force anything (we'll not deprecate the Form component soon), just to promote current web development best practices, so Symfony can stay attractive, even compared to the full-stack JS ecosystem.

Anyway, I would be interested to know what are the technical drawbacks associated to this strategy a developper can find (I'm well aware of the HR and organizational issues related to JS for forms, but I haven't found technical ones yet).

@tgalopin
Copy link
Contributor

As Kevin explained his point of view on this, I will explain mine too ;) .

1/ I am totally in favor of decoupling flash bags and sessions in order to keep the default feature (based on sessions) but allow flash bags to be transmitted differently (messenger + socket.io, API endpoint, etc.). This would allow great possibilities and still keep the current code working.

2/ While I do agree with Kevin on the observations, I don't think the logic behind his conclusions are entirely sound:

The observation is clear: nowadays, users expect pages that don't refresh, load fast and display a nice status message/icon while they are working on it. This observation is definitely real.

However, I don't think this necessarily translates to "use JavaScript to generate forms, and a web API (REST or GraphQL) to handle them". Saying there is an equivalence between what a user want and a specific way to implement this need is IMO not valid. For instance, there are multiple libraries like https://github.com/MoOx/pjax that helps classical apps become more user friendly (and achieve great results, GitHub itself being a great example of this) while still using the classical pattern.

I do agree that Javascript forms in combination with APIs are becoming very widespread in new projects, and I like this. I just don't agree on the direct implication "users wants better DX => let's put Javascript on forms", UX is much more complicated than that IMO. You will achieve better UX result in PHP without Javascript if you are not familiar with Javascript and don't control every aspect of it properly. Which brings me to my third point ...

3/ I think a reccurent problem we have in Symfony is our lack of integrated Javascript framework. Yes, I know, we are a backend framework, we shouldn't be tied to a front-end framework, etc. But I actually think things have changed: nowadays, backend and frontend are being more and more coupled to achieve the UX and features users want. One typical example of this is definitely forms, as we are discussing here.

Moreover, having an "official" integrated Javascript framework would be a great way to address the issue I raise in 2: many Symfony developers don't know Javascript. Which is fine if you do only APIs but which is becoming more and more problematic otherwise. By adopting a specific framework integration, we would help Symfony developers to target a specific thing to learn, it would be much easier for them to know what they should have a look at in the vast Javascript ecosystem.

I am really against trying to migrate away from the current forms / validation / flash messages system until we have at least the same level of DX, integration, accessibility and easy of usage in the new version. Symfony forms currently generates the view, handles CSRF and validation, display translated error messages, populate a PHP data-object we can persist and allow for listeners and extensions to change the behavior of the form itself, from userland or from bundles.

I think we are far from all these features in the Javascript + API way, which necessarily means developers will need to write more code. API-platform definitely helps a lot there compared to Symfony, but (a) we can't expect everyone to use API-platform and (b) it is not a part of the core package people are downloading when running composer require form.

This is why I think the best way we could keep the great DX experience of current forms is by being much more linked to a Javascript framework and provide tools both inside Symfony and this framework to allow these kind of features to be implemented. Until then, I feel removing / migrating towards something where the workload for developers increases is definitely a -1 for me.

@dunglas
Copy link
Member

dunglas commented Oct 17, 2018

nowadays, users expect pages that don't refresh, load fast and display a nice status message/icon while they are working on it.

True, but it wasn't exactly my point. I wasn't speaking about user expectations, but of the evolution of the web platform itself (the WHATWG/W3C/IETF standards) and of the frontend ecosystem.
pjax is nice, but it's a transition tool: it's awesome for existing projects, but for new projects, it doesn't make much sense from a technical point of view to use this of React/Vue/Angular (however, I do agree that it can make a lot of sense from a HR point of a view).

I think we are far from all these features in the Javascript + API way, which necessarily means developers will need to write more code.

From my experience, it's not true. A form written in Vue + API Platform is easier to understand, quicker to write and contains less LOC than one written with the form component.

I am really against trying to migrate away from the current forms / validation / flash messages system until we have at least the same level of DX, integration, accessibility and easy of usage in the new version. Symfony forms currently generates the view, handles CSRF and validation, display translated error messages, populate a PHP data-object we can persist and allow for listeners and extensions to change the behavior of the form itself, from userland or from bundles.

API Platform already has all of these features except the ones related to bundles (because there are no "bundles" in JS, but you can use dynamic React or Vue components for that).

I think a reccurent problem we have in Symfony is our lack of integrated Javascript framework.

I kind of agree. It's very important to have "official ways". However, it's better design to make the frontend part and the backend part independent (using standards like Hydra, or OpenAPI, as done in API Platform). It also allows to reuse the backend part for mobile apps, Electron apps, IoT...

In API Platform:

  • the libraries recommended and installed by default are React + Redux. The experience is smooth if you use them, you've nothing to configure, everything work out of the box (frontend and backend)
  • but, VueJS is also supported (just some config to change)
  • but, the backend part is 100% JS-agnostic and can work with any framework (even if we provide a React and Vue integration)

That being said, API Platform (backend part) is already shipped with Symfony 4 (composer require api).
Maybe should we just update the Symfony documentation to explain how to use API Platform's frontend tools (the form/CRUD generator for React and Vue, and API Platform Admin), for the ones that want to create "modern" SPA/PWA?

@nicolas-grekas
Copy link
Member Author

Just don't forget about the "rule of least power" ;)

javiereguiluz added a commit to symfony/symfony-docs that referenced this issue Oct 29, 2018
…javiereguiluz)

This PR was merged into the 3.4 branch.

Discussion
----------

Revert a change related to flash messages and sessions

This was done a few days ago (e6ce2f4) but there's an ongoing discussion about it in Symfony (symfony/symfony#28804) and some people are complaining on slack about the changed code. So let's revert for now to the original code.

Commits
-------

f96118b Revert a change related to flash messages and sessions
@ghost
Copy link

ghost commented May 22, 2019

As Kevin explained his point of view on this, I will explain mine too ;) .

1/ I am totally in favor of decoupling flash bags and sessions in order to keep the default feature (based on sessions) but allow flash bags to be transmitted differently (messenger + socket.io, API endpoint, etc.). This would allow great possibilities and still keep the current code working.

2/ While I do agree with Kevin on the observations, I don't think the logic behind his conclusions are entirely sound:

The observation is clear: nowadays, users expect pages that don't refresh, load fast and display a nice status message/icon while they are working on it. This observation is definitely real.

However, I don't think this necessarily translates to "use JavaScript to generate forms, and a web API (REST or GraphQL) to handle them". Saying there is an equivalence between what a user want and a specific way to implement this need is IMO not valid. For instance, there are multiple libraries like https://github.com/MoOx/pjax that helps classical apps become more user friendly (and achieve great results, GitHub itself being a great example of this) while still using the classical pattern.

I do agree that Javascript forms in combination with APIs are becoming very widespread in new projects, and I like this. I just don't agree on the direct implication "users wants better DX => let's put Javascript on forms", UX is much more complicated than that IMO. You will achieve better UX result in PHP without Javascript if you are not familiar with Javascript and don't control every aspect of it properly. Which brings me to my third point ...

3/ I think a reccurent problem we have in Symfony is our lack of integrated Javascript framework. Yes, I know, we are a backend framework, we shouldn't be tied to a front-end framework, etc. But I actually think things have changed: nowadays, backend and frontend are being more and more coupled to achieve the UX and features users want. One typical example of this is definitely forms, as we are discussing here.

Moreover, having an "official" integrated Javascript framework would be a great way to address the issue I raise in 2: many Symfony developers don't know Javascript. Which is fine if you do only APIs but which is becoming more and more problematic otherwise. By adopting a specific framework integration, we would help Symfony developers to target a specific thing to learn, it would be much easier for them to know what they should have a look at in the vast Javascript ecosystem.

I am really against trying to migrate away from the current forms / validation / flash messages system until we have at least the same level of DX, integration, accessibility and easy of usage in the new version. Symfony forms currently generates the view, handles CSRF and validation, display translated error messages, populate a PHP data-object we can persist and allow for listeners and extensions to change the behavior of the form itself, from userland or from bundles.

I think we are far from all these features in the Javascript + API way, which necessarily means developers will need to write more code. API-platform definitely helps a lot there compared to Symfony, but (a) we can't expect everyone to use API-platform and (b) it is not a part of the core package people are downloading when running composer require form.

This is why I think the best way we could keep the great DX experience of current forms is by being much more linked to a Javascript framework and provide tools both inside Symfony and this framework to allow these kind of features to be implemented. Until then, I feel removing / migrating towards something where the workload for developers increases is definitely a -1 for me.

@tgalopin

I am commenting on this because I want to emphasis something I think is common in alot of places.

Where I currently work (and honestly, where I have worked in the past) our technology stack is dictated (more or less). Right now, I'm heavily working with symfony on the backend. The thing that causes complications for me, and I imagine alot of developers is this:

  1. The place where I work hangs on the Symfony recommendations as gospel, and tends to be very rigid in introducing newer, more modern practices unless Symfony recommends them (its a long story, but this reality is very common for lots of unsung developers out there, and not just with php/symfony of course)

  2. Because of number 1, its been really hard to move UX design forward, even though our end users are consistently demanding features that would fall in the realm of being better suited to be handled by DOM APIs and JavaScript as opposed to muddling through PHP, especially since our user base is growing substantially. We only adopted Webpack because of symfony/webpack-encore, and that was considered a big change for our front end. I'm only noting this to give you some idea of where I'm coming from. The needle only moves when symfony does, more or less. (At least, if I want a happy path to getting certain things approved for usage on projects 😆)

  3. If you actually do start to move the needle and endorse these solutions publicly and explicitly, especially in LTS you give alot more power to people who want to have more progress UIs and moving that needle forward, thereby helping out the entire ecosystem as a result.

I can elaborate more, (I don't want this to be too "ranty"), but for me, if in the Symfony docs it had some explicit recommendations for doing UI in such a way, it would go a long way in both making my job easier (because I could leverage the proper APIs in the proper places) and put alot of bosses at ease with their teams adopting more progressive standards and moving more quickly to modern solutions (which is better for all of us in the ecosystem).

To reiterate, I suspect I'm probably representing a lot more developers than those that commend on github or issue trackers. I know alot of people developing php/symfony who feel this way but don't feel like they can voice it publicly. The so called silent developer majority, if you will.

I don't think github uses pjax anymore

@ghost
Copy link

ghost commented May 22, 2019

nowadays, users expect pages that don't refresh, load fast and display a nice status message/icon while they are working on it.

True, but it wasn't exactly my point. I wasn't speaking about user expectations, but of the evolution of the web platform itself (the WHATWG/W3C/IETF standards) and of the frontend ecosystem.
pjax is nice, but it's a transition tool: it's awesome for existing projects, but for new projects, it doesn't make much sense from a technical point of view to use this of React/Vue/Angular (however, I do agree that it can make a lot of sense from a HR point of a view).

I think we are far from all these features in the Javascript + API way, which necessarily means developers will need to write more code.

From my experience, it's not true. A form written in Vue + API Platform is easier to understand, quicker to write and contains less LOC than one written with the form component.

I am really against trying to migrate away from the current forms / validation / flash messages system until we have at least the same level of DX, integration, accessibility and easy of usage in the new version. Symfony forms currently generates the view, handles CSRF and validation, display translated error messages, populate a PHP data-object we can persist and allow for listeners and extensions to change the behavior of the form itself, from userland or from bundles.

API Platform already has all of these features except the ones related to bundles (because there are no "bundles" in JS, but you can use dynamic React or Vue components for that).

I think a reccurent problem we have in Symfony is our lack of integrated Javascript framework.

I kind of agree. It's very important to have "official ways". However, it's better design to make the frontend part and the backend part independent (using standards like Hydra, or OpenAPI, as done in API Platform). It also allows to reuse the backend part for mobile apps, Electron apps, IoT...

In API Platform:

  • the libraries recommended and installed by default are React + Redux. The experience is smooth if you use them, you've nothing to configure, everything work out of the box (frontend and backend)
  • but, VueJS is also supported (just some config to change)
  • but, the backend part is 100% JS-agnostic and can work with any framework (even if we provide a React and Vue integration)

That being said, API Platform (backend part) is already shipped with Symfony 4 (composer require api).
Maybe should we just update the Symfony documentation to explain how to use API Platform's frontend tools (the form/CRUD generator for React and Vue, and API Platform Admin), for the ones that want to create "modern" SPA/PWA?

@dunglas

Just so I don't reiterate context, see my other post in this thread

For me, and I suspect many users of symfony, its the lack of explicit recommendations and practices in symfonys documentation in their best practices guide that makes the adoption for things slow. If this was in the best practices guide (and I think it should be for the upcoming LTS release 4.4), it would be no-brainer sign off from the HR perspective.

So even with the flex integration, the issue for me, and I suspect a lot of others, is the fact its not explicitly recommended as the best practice going forward. I think this is what needs to change, more than anything, is that the best practice recommendation be updated to reflect this. From the framework's perspective, best practice means everything, even if you don't have to or want to follow it, it gives a lot of wood behind the arrow, so to speak.

Thats something i'd like to see.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
RFC RFC = Request For Comments (proposals about features that you want to be discussed)
Projects
None yet
Development

No branches or pull requests

8 participants