12. Conclusion
Ce document a présenté la construction d'une application web MVC avec le framework [Flask] : une application dont les pages HTML sont fabriquées par le serveur, avec des vues [Jinja2], sans framework [JavaScript] côté navigateur. Il a suivi pas à pas la progression du cours [Spring MVC], lui-même issu des cours [ASP.NET Core MVC] et [NestJS] : des actions et du routage vers les vues, les formulaires, l'internationalisation, la sécurité et l'accès aux données, puis une étude de cas complète.
Les mêmes 28 exemples et la même application ont ainsi été écrits avec quatre frameworks, en [TypeScript], en [C#], en [Java] et en [Python]. Les notions sont les mêmes ; seuls les noms et les mécanismes changent. Les correspondances entre [Spring MVC] et [Flask] :
Spring MVC | Flask |
classe [@SpringBootApplication], classes [@Configuration], méthodes [@Bean] | fabrique [create_app], objets rangés dans [app.extensions] |
fichier [pom.xml], starters [Maven] | fichier [requirements.txt], environnement virtuel, [pip] |
[application.properties], profils, [@ConfigurationProperties] | [config.py], [config_<profil>.py], variables [FLASK_...] ([app.config]) |
injection de dépendances : beans singletons, [@Service], [@Component] | objets créés à la main par la fabrique, retrouvés par [current_app] |
[@Controller], [@GetMapping], [@PostMapping], nom de vue ou [redirect:...] | blueprints, [@bp.get], [@bp.post], [render_template], [redirect] |
liaison de modèle, [@RequestParam], convertisseurs | [request.args], [request.form], convertisseurs de [Werkzeug] ([<int:id>]) |
[Bean Validation] : [@NotBlank], [@Min], [@Max]..., [@Valid], [BindingResult] | [Pydantic] (paramètres, JSON) ; [WTForms] : validateurs, [form.validate()], [form.errors] |
vues [Thymeleaf] ([.html]), [th:text], [th:each], [th:if] | vues [Jinja2], [{{ }}], [{% for %}], [{% if %}] |
gabarit et fragments ([th:replace], [th:fragment]) | [{% extends %}] et blocs, [{% include %}], macros |
[@ControllerAdvice] et [@ModelAttribute] | processeur de contexte ([@app.context_processor]) |
attributs flash ([RedirectAttributes]) | messages flash ([flash], [get_flashed_messages]), dans le cookie de session |
filtres de servlet, intercepteurs | middleware WSGI, [before_request], [after_request], [teardown_request] |
[@ControllerAdvice] / [@ExceptionHandler], [ErrorController] | [@app.errorhandler] |
[Spring Security] : [SecurityFilterChain], serveur de ressources, [@PreAuthorize] | [before_request] et décorateurs écrits à la main ([PyJWT], [bcrypt]) |
protection CSRF de [Spring Security] | [CSRFProtect] de [Flask-WTF] |
dictionnaires JSON lus par un [MessageSource], [#{...}], [LocaleResolver] | dictionnaires JSON, fonction [t(...)] des vues, [g.langue] fixée par un [before_request] |
[Spring Data JPA] et [Hibernate], [JpaRepository], requêtes dérivées, [JPQL] | [SQLAlchemy] : entités déclaratives, [select(...)], sessions, classes DAO écrites à la main |
[@Transactional], [TransactionTemplate] | [with sessions.begin() as session:] |
[@Version], géré par [Hibernate] | [version_id_col], géré par [SQLAlchemy] |
[mvnw spring-boot:run], [Spring Boot DevTools] | [python app.py] en mode debug (rechargement automatique) |
archive exécutable ([java -jar]), [Tomcat] intégré | serveur WSGI : [Waitress], [Gunicorn] |
Par rapport à [Spring MVC], on retiendra surtout :
- [Flask] est un micro-framework : il fournit le routage, les requêtes et les réponses, les vues [Jinja2], la session, et s'arrête là. Tout le reste (validation, formulaires, sécurité, accès aux données, traduction) est confié à des bibliothèques choisies par le développeur, ou écrit par lui. C'est plus de code à écrire, mais un code visible : rien ne se passe « par magie », et l'on peut suivre chaque objet de sa création (dans [create_app]) à son utilisation ;
- il n'y a pas de conteneur d'injection de dépendances : les objets partagés sont créés par la fabrique, rangés dans [app.extensions], et retrouvés par [current_app]. Pour une application de cette taille, c'est simple et suffisant ;
- les objets [request], [g], [session], [current_app] sont des mandataires qui désignent, pendant une requête, les objets de cette requête. Ils évitent de passer la requête de fonction en fonction, mais ne sont utilisables que pendant le traitement d'une requête (ou dans un contexte d'application créé à la main) ;
- les décorateurs de [Python] jouent le rôle des annotations de [Java] : routes, marques ([@publique]), contrôles d'accès ([@roles_requis]). Mais un décorateur est une simple fonction, que l'on écrit soi-même en quelques lignes ;
- [Python] est un langage dynamiquement typé : les annotations de type ([list[Medecin]], [Protocol], classes génériques) documentent le code et guident l'éditeur, mais ne sont pas vérifiées à l'exécution. Des outils comme [Pylance] (dans [Visual Studio Code]) ou [mypy] les vérifient avant l'exécution ;
- [SQLAlchemy] demande d'écrire la couche DAO (quelques lignes par requête), mais ses requêtes, construites avec des objets [Python], restent proches du SQL qu'elles produisent, et l'affichage des ordres SQL ([SQL_ECHO]) permet de vérifier ce qui est envoyé à la base. Le chargement des relations se décide explicitement, requête par requête ;
- les vues [Jinja2] mélangent HTML et balises [{{ }}] / [{% %}] : elles ne sont pas des pages HTML valides comme celles de [Thymeleaf], mais leur langage, proche de [Python], est puissant (filtres, macros, héritage de gabarits) et l'échappement automatique protège contre l'injection de HTML.
L'étude de cas montre qu'une application HTML classique, sans [JavaScript] indispensable, reste une solution simple et robuste : chaque page est une URL, le bouton « précédent » du navigateur fonctionne, et le serveur contrôle tout. Le peu de [JavaScript] utilisé (les fenêtres de confirmation) améliore le confort sans être nécessaire au fonctionnement.
Pour aller plus loin, on pourra consulter la documentation de [Flask] (flask.palletsprojects.com), celles de [Jinja2] (jinja.palletsprojects.com), de [Werkzeug] (werkzeug.palletsprojects.com), de [WTForms] (wtforms.readthedocs.io) et de [Flask-WTF] (flask-wtf.readthedocs.io), de [SQLAlchemy] (docs.sqlalchemy.org), de [Pydantic] (docs.pydantic.dev), et comparer cette application à ses sœurs [Spring MVC], [ASP.NET Core MVC] et [NestJS].