Introduction
Applications web
1. Vue d’ensemble
Débutons par un peu de sémantique.
Une application web est un logiciel construit au-dessus d’un serveur web et utilisé par un client web qui s’appuie sur le protocole HTTP.
Il existe de nombreux serveurs web open source, tels qu’Apache ou Nginx. Ces serveurs sont adaptés à un environnement de production, ils sont robustes, sécurisés et performants.
Django dispose également d’un serveur web embarqué. Ce dernier est utilisé pour le développement. Démarrer le serveur Django signifie démarrer ce serveur web embarqué. Ce dernier n’est pas adapté à la production, en particulier pour un site qui demande de bonnes performances et surtout, il n’a jamais fait l’objet d’audits de sécurité, car il est vraiment fait pour le développement.
Un serveur web est essentiellement un programme qui va passer son temps à attendre. Il utilise le protocole HTTP qui est construit au-dessus du protocole TCP. Lorsqu’un client émet une requête, il crée une connexion avec le serveur. Le serveur accepte la connexion, donne la requête à un thread qui va la traiter puis il se remet en attente pour la prochaine connexion.
Le thread qui prend la requête va la traiter selon le code que vous aurez écrit dans votre application puis va renvoyer une réponse.
Le client web usuel est votre navigateur. Lorsque vous tapez une adresse dans votre barre d’adresse, le client web émet une requête de type GET et le serveur lui renvoie une réponse. Si tout se passe bien, le code de la réponse est 200 (OK) et le corps de la réponse contient le code HTML de la page à afficher.
Dans ce code HTML, il y a des liens vers des fichiers CSS, JavaScript, ou encore des images, référencées par des chemins. Votre client web va alors créer une nouvelle requête GET par élément à récupérer et attendre les diverses réponses pour gérer la mise en page.
Lorsque vous cliquez sur un lien ou validez un formulaire de recherche, le client va également créer une requête de type GET sur un chemin particulier.
Enfin, lorsque vous remplissez un formulaire destiné à collecter et traiter des données, le client web va envoyer une requête de type POST. Les données collectées sont ainsi transmises au serveur.
C’est le protocole HTTP qui définit des verbes :
-
GET : demander une donnée au serveur ;
-
POST : transmettre une donnée au serveur.
Bien entendu, un client peut générer plusieurs requêtes simultanément, il n’a pas besoin d’attendre la réponse à l’une d’entre elles pour émettre la suivante. De la même manière, un serveur peut répondre à plusieurs clients en même temps.
Au-delà de cela, le client web peut aussi être une autre application, comme une autre application web, ou encore une application mobile. Pour communiquer, ces applications vont échanger des données via des services web. Le protocole HTTP définit, entre autres :
-
GET : demander une donnée ;
-
POST : créer une donnée ;
-
PUT : mettre à jour une donnée ;
-
PATCH : mettre à jour partiellement une donnée ;
-
DELETE : supprimer une donnée.
Aujourd’hui, dans les applications modernes, il est courant de construire une application back-end qui offre des services web et une application front-end qui gère la partie affichage et va consommer ces services web.
On peut résumer ce que l’on vient de dire par ce graphique :
Fonctionnement simplifié d’une application web
Pour aller un peu plus loin, il faut savoir que la requête comme la réponse embarquent avec elles des en-têtes, c’est-à-dire des métadonnées à propos des données qu’elles transportent. Cela permet d’informer sur le type d’information transportée, sur la durée de validité des données, etc.
En fonction de ces métadonnées, le client web pourra décider de mettre en cache certaines données pour ne pas avoir à les redemander et ainsi économiser le nombre de requêtes à créer et la charge du serveur.
2. Focus côté serveur
En tant que développeur d’application web, une grande partie du travail à réaliser est côté serveur. C’est en effet dans cette partie que va résider tout le code fonctionnel de l’application. Le principe de toute application est de gérer des données, c’est-à-dire de gérer comment elles sont modélisées et comment elles sont exposées.
Django utilise le patron d’architecture MVT, pour modèle, vue, template.
La partie « modèle » consiste à décrire nos données. On va, pour cela, utiliser la programmation objet et créer des modèles décrivant ces objets et leurs interactions...
Présentation de Python
1. Introduction
Python est un langage gratuit et libre de droits (sous une licence proche de la BSD) qui présente la caractéristique d’avoir une barrière d’entrée assez peu élevée. Il est donc assez approchable et il permet de faire beaucoup de choses avec peu d’efforts.
Initialement créé en 1989 et publié pour la première fois en 1991, il a depuis beaucoup évolué et est aujourd’hui l’un des langages les plus populaires.
En ce qui nous concerne, nous allons devoir créer des modèles, pour modéliser les données que nous allons manipuler. Cela se fera en utilisant le paradigme de programmation objet, c’est-à-dire par la création de classes. Tout comme la gestion des formulaires, des vues ou des pages d’administration, par exemple.
Nous allons également devoir créer quelques algorithmes pour décrire la logique derrière notre application, c’est-à-dire la manière dont nous allons manipuler nos objets.
Au-delà du fonctionnement du paradigme objet en Python, Django rajoute sa « propre patte » en permettant de faciliter le travail encore plus pour le développeur.
Si vous n’êtes pas encore familier avec Python, vous aurez tout le loisir d’apprendre progressivement tout au long de cet ouvrage.
2. Tutoriel
En Python, tout est objet. Lorsque l’on déclare une variable, nous n’avons pas besoin de la typer, le type est porté par le contenu de la variable. Du reste, le type d’une variable peut changer au cours du temps.
>>> entier = 42
Dans cet exemple, j’ai déclaré une variable nommée entier et ayant pour valeur 42. 42 est ce que l’on appelle un littéral, c’est-à-dire une valeur écrite en dur dans le code.
Pour créer une chaîne de caractères, il est possible d’utiliser la double quote ou la simple quote :
>>> chaine = "ceci est une chaîne de caractères"
>>> chaine = 'ceci est une chaîne de caractères'
Les deux objets précédents sont rigoureusement les mêmes.
Il est possible de créer une chaîne de caractères dynamique, c’est-à-dire dépendante de la valeur d’une variable.
>>> f"la valeur est {entier}."
la valeur est 42.
Pour cela, on préfixe la double quote ou la simple quote par un f.
Il est également possible de créer une liste d’objets :
>>> liste = [1, 2, 3, "chaîne", entier]
Ici, ma liste contient cinq objets, les nombres 1, 2 et 3, puis une nouvelle chaîne de caractères, puis le nombre 42, car c’est la valeur de la variable entier qui a été référencée ici.
Il est possible d’utiliser l’opérateur crochet pour obtenir un élément en particulier de la liste. Le premier indice est toujours 0 :
>>> liste[0]
1
>>> liste[4]
42
>>> liste[-1]
42
Cette dernière instruction montre qu’il est possible de partir de la fin en utilisant des indices négatifs.
Enfin, il est possible de créer un dictionnaire pour représenter une structure de données plus élaborée :
>>> data = {
... "user_id": 1,
... "ids": [12, 14, 13],
... "context": {
... "filter": "active",
... "display": False,
... }
... }
On notera au passage qu’il existe deux objets particuliers qui sont True et False pour représenter respectivement le booléen vrai et faux ainsi qu’un objet None pour représenter la valeur nulle ou non existante.
Pour écrire des blocs conditionnels, la syntaxe à utiliser...
Présentation de Django
1. Historique
Django est créé fin 2003 par des développeurs web travaillant pour un journal américain. Ce framework avait pour but de créer un outil de gestion de contenu générique et était utilisé pour la version en ligne de ce journal.
L’un des deux développeurs, guitariste et admirateur de Django Reinhardt donnera le prénom de ce grand artiste au framework.
En juillet 2005, le projet est publié sous licence BSD (licence libre qui impose très peu de contraintes pour l’utilisation et la distribution des logiciels). Une communauté se forme autour du projet.
En décembre 2005, une nouvelle méthode de versionnement est mise en place, la version 0.96 est publiée. Le projet évolue vite avec beaucoup de corrections et devient plus orienté production-ready.
En juin 2008, il se forme la Django Software Foundation (DSF), un organisme à but non lucratif qui a pour objet l’organisation de la communauté des développeurs Django et la maintenance du projet Django.
La version 1.0 est publiée le 3 septembre 2008 (https://docs.djangoproject.com/en/5.2/releases/1.0/). Des changements importants ont été effectués et cette version coupe la compatibilité avec les versions précédentes. Pour rappel, c’est trois mois plus tard que sort Python 3.0, qui lui aussi coupe la compatibilité avec Python 2.X. Il est décidé que pour le futur, tout code écrit sur une version 1.X de Django sera compatible avec toute autre version suivante de la branche 1.
La version 1.3 est publiée le 23 mars 2011. Pour la première fois sont définies des dates de support :
-
un support principal (qui dure un an pour cette version) ;
-
un support étendu (qui dure onze mois supplémentaires).
La version 1.4 est publiée le 23 mars 2012, soit un an après. C’est la première version à support long terme (LTS) :
-
un support principal (qui dure un an pour cette version) ;
-
un support étendu (qui dure dix-huit mois supplémentaires).
À partir de cet instant, il est défini qu’une version sur trois sera à support long terme. La durée des différents supports évoluera à chaque version, jusqu’à être définitivement fixée à la sortie de la version 2.0.
En attendant, la version 1.7, sortie le 2 septembre 2014, est celle qui apportera un changement structurel très important à l’architecture des applications Django, la modernisera beaucoup et ajoutera le système...
Alternatives à Django
1. Monolithe Full-stack
Django est ce que l’on appelle un framework full-stack monolithique. Full-stack, car il permet d’adresser toutes les problématiques back-end, c’est-à-dire liées à l’application côté serveur, tout comme celles front-end, c’est-à-dire liées à l’expérience utilisateur, côté client.
Le côté monolithique signifie que tout le nécessaire est déjà intégré et que tous les composants sont faits pour fonctionner parfaitement ensemble.
Nous avons vu dans la section précédente les différentes fonctionnalités d’un framework. Certains ne font que la gestion du routage et la création de vues. Il faut choisir un module supplémentaire pour gérer la partie modèle, un autre pour gérer les templates, un autre pour gérer l’authentification ou les autorisations...
Le côté monolithique permet d’avoir clé en main tous les outils pour répondre à toutes les problématiques les plus classiques et d’être certain que tous les outils sauront fonctionner ensemble.
Il existe au moins un autre framework web monolithique nommé Emmet (https://github.com/emmett-framework/emmett) qui est plus léger. Il présente beaucoup moins de fonctionnalités, mais est plus direct à utiliser.
Il existe d’autres frameworks monolithiques, mais agnostiques en ce qui concerne l’ORM. Un ORM est la partie du framework qui gère la base de données, à la fois la manière de l’adresser (bas niveau de l’ORM, c’est-à-dire le dialecte spécifique de la base de données, la gestion de ses extensions...) mais aussi la manière de modéliser ces données (haut niveau de l’ORM).
On peut citer Flask (https://github.com/pallets/flask), Quart (https://github.com/pallets/quart, une réécriture de Flask en asynchrone) ou encore Pyramid (https://github.com/Pylons/pyramid), une solution très professionnelle et très rapide à mettre en place.
2. Microservices/API REST
Il existe également des frameworks web qui sont spécialisés pour créer des API REST ou des microservices en recherchant la fiabilité et de hautes performances. Pour aller chercher cette performance, ils sont construits de manière asynchrone et utilisent ASGI.
Ils sont agnostiques au niveau des ORM, mais également au niveau des moteurs de templates, par exemple. Leur utilisation première n’étant pas la génération de code HTML, il est néanmoins possible de le faire en embarquant un de ces moteurs, comme Jinja2 (https://github.com/pallets/jinja) ou Chameleon (https://github.com/malthe/chameleon).
FastAPI (https://github.com/tiangolo/fastapi) est l’un des plus emblématiques...