Rework introduction
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Fred Pauchet 2022-06-12 17:09:19 +02:00
parent e7b66702dc
commit 862d2d01f6
6 changed files with 79 additions and 38 deletions

View File

@ -9,10 +9,12 @@ Expliquer pourquoi une API est intéressante/primordiale/la première chose à r
\begin{itemize}
\item
Intéressante: ouverture
\item Primordiale: services
\item La première chose à réaliser: mobile-first
\item Le cadet de nos soucis: monolithique (cf. Rework)
\item
Primordiale: services
\item
La première chose à réaliser: mobile-first
\item
Le cadet de nos soucis: monolithique (cf. Rework)
\end{itemize}
Voir peut-être aussi
@ -84,14 +86,11 @@ class Contract(models.Model):
)
\end{minted}
\includegraphics{images/rest/models.png}
\section{Mise en place}
La configuration des points de terminaison de notre API est relativement touffue.
La configuration des points de terminaison de notre API peut être relativement touffue.
Pour cette raison, il convient de s'infliger à suivre une structure qui soit similaire pour chaque point de terminaison \cite[Predictability, Rule \#1]{django_for_startup_founders}.
Il convient de:
@ -123,6 +122,8 @@ Il convient de:
Et finalement ajouter quelques paramètres au niveau de notre application.
\end{enumerate}
\section{Django Rest Framework}
\subsection{Serialiseurs}
Les sérialiseurs agissent litérallement comme des \texttt{forms}, mais au niveau de l'API.
@ -231,7 +232,7 @@ En nous rendant sur l'URL \texttt{http://localhost:8000/api/v1}, nous obtiendron
\includegraphics{images/rest/api-first-example.png}
\section{Modéles et relations}
\subsection{Modéles et relations}
Plus haut, nous avons utilisé une relation de type \texttt{HyperlinkedModelSerializer}. C'est une bonne manière pour autoriser des relations entre vos instances à partir de l'API, mais il faut reconnaître que cela reste assez limité. Pour palier à ceci, il existe {[}plusieurs manières de représenter ces
\url{https://www.django-rest-framework.org/api-guide/relations/}:
@ -322,3 +323,34 @@ class PeopleSerializer(serializers.HyperlinkedModelSerializer):
Nous ne faisons donc bien que redéfinir la propriété \texttt{contract\_set} et indiquons qu'il s'agit à présent d'une instance de \texttt{ContractSerializer}, et qu'il est possible d'en avoir plusieurs. C'est tout.
\section{Alternatives}
Django-Rest-Framework est une librarie complète qui ajoute énormément de possibilités.
Cependant \cite{django_for_startup_founders}:
\begin{enumerate}
\item
La documentation est \textbf{réellement} compliquée.
Tout nouveau développeur doit appréhender, comprendre et assimiler cette documentation et tous les concepts sous-jacents.
Ceci inclut notamment le fait que tous les verbes HTTP ont été "traduits" (GET -> retrieve, POST -> create, ...).
Ceci a du sens par rapport à la définition d'une interface REST-compliant, mais ajoute une complexité mentale relativement lourde.
\item
Certains concepts de réutilisation sont tellement compliqués qu'ils prennent plus de temps à mettre en place qu'à écrire une ligne de code Python classique
\item
Les sérialiseurs peuvent rapidement devenir difficiles à lire ou relire, spécifiquement lorsque nous utilisons des \textit{nested serializers} ou lorsque les concepts de désérialisation sont abordés.
\end{enumerate}
\subsection{Marshmallow}
\textit{Marshmallow} est une alternative plus légère à Django-Rest-Framework, et qui présente une interface plus claire, ainsi qu'une documentation plus concise et facile à comprendre.
Une solution plus facile que les sérializeurs de DRF consistera à
\begin{enumerate}
\item
Gérer la validation de données en utilisant Marshmallow
\item
Sérialiser les données en utilisant du code Python \cite{django_for_startup_founders}.
\end{enumerate}

View File

@ -270,7 +270,7 @@ Les \href{https://google.github.io/styleguide/pyguide.html\#38-comments-and-docs
L'exemple donné dans les guides de style de Google est celui-ci:
\begin{listing}[!ht]
\begin{minted}{python}
\begin{minted}[tabsize=4]{python}
def fetch_smalltable_rows(
table_handle: smalltable.Table,
keys: Sequence[Union[bytes, str]],
@ -284,9 +284,9 @@ L'exemple donné dans les guides de style de Google est celui-ci:
Args:
table_handle: An open smalltable.Table instance.
keys: A sequence of strings representing the key of each table
row to fetch. String keys will be UTF-8 encoded.
row to fetch. String keys will be UTF-8 encoded.
require_all_keys: Optional; If require_all_keys is True only
rows with values set for all keys will be returned.
rows with values set for all keys will be returned.
Returns:
A dict mapping keys to the corresponding table row data

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -0,0 +1 @@
<mxfile host="Electron" modified="2022-06-12T14:44:34.104Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/16.5.1 Chrome/96.0.4664.110 Electron/16.0.7 Safari/537.36" etag="lAWVv-msopTdmLAI8NAh" version="16.5.1" type="device"><diagram id="psmWZwzM_4FqpaO-ajCI" name="Page-1">7VhNc5swEP01TE/OgImxc2wcJ50mbTPJIR+XjgxrUCMQEQJDf30lEAYix4kTp6YzvTDap0VCb/ctC4Y9DfMzhuLgG/WAGEPTyw37xBgOj6yJuEqgqIDJ6LACfIa9CrIa4Br/BgWaCk2xB0nHkVNKOI67oEujCFzewRBjdNl1W1DS3TVGPmjAtYuIjt5gjwfqFMNxg38B7Af1zpZzVM2EqHZWJ0kC5NFlC7Jnhj1llPJqFOZTIJK7mpfqvtNnZlcPxiDir7mB3F+P6cXifPDz9jhPxoNJhr2BNVQPx4v6xOAJApRJGQ+oTyNEZg16zGgaeSCXNYXV+FxQGgvQEuAv4LxQ0UQppwIKeEjULOSY37bGd3Kpg5GyTnK1cmkULeMSGA6BA6uxiLPitm20VpJms1Rp1Wvp1Ck2E5oyFzbwpZKXI+YD3+Cnsl5y2dpABeYMqDgFK4QDA4I4zrrJhlTO+iu/JqxioCK7RZTVU2eIpGqnE2NqG5+P5inX4t+Kk4eSYBXnZYA5JDEq+VkKsQtM5HQszTD3pfoPvIV3kAhy+LMMZ8A45Bs5UbO20k3RNZctFSooaAmwdts5hyONw1Mc9Zc8q8ve0NwzfZalcdXXQvPXi8rklUWljmlPqspEU8RUvoRzTIUuHBTKHI/mSVxy4xBxsuM5EyNfjsr6I85jkk8QZZjJO0PJnObpgWwfIOE4Eoei79PcDqRlOU+lpSnLMtdIa/Rh0tLL+yzhA1fy9pjKKykprEp+TCh+hmnBsfBLI0lv6rql/yQRlmGf7lO9jWLvWjMvqbcR7F1Hr7tWb63Kl+Vr71q+6tZLimU4Vy50sUiAa3m12uEdqWZqqXZVpZWbxtWAKZGulTFB4hLRNBN7ge4jRJj0QOG22TeF683HjxT/85Lc+EqVh1b207b/HVq1X6nVUa/etJb+qv2+Rib/G6ptw2w5/YqzrcVZCzILaDhPkx1VOnvUqXTWmq8s+4M+Ex6Ce4gOr77eTLMgXjyS6NwfD/b6O+JNRc3aLqk3FLQnSfjG1He2qXB7S3RHS3T1RyJEjAHTW4OyhWWUkDlyH/bdIBzWLXctmw/sEITZ/COs+rjmR6s9+wM=</diagram></mxfile>

View File

@ -9,44 +9,52 @@
En fonction de vos connaissances et compétences, la création d'une nouvelle application est une étape relativement facile à mettre en place.
Le code qui permet de faire tourner cette application peut ne pas être élégant, voire buggé jusqu'à la moëlle, il pourra fonctionner et faire "preuve de concept".
Les problèmes arriveront lorsqu'une nouvelle demande sera introduite, lorsqu'un bug sera découvert et devra être corrigé ou lorsqu'une dépendance cessera de fonctionner ou d'être disponible.
Or, une application qui n'évolue pas, meurt.
Toute application est donc destinée, soit à être modifiée, corrigée et suivie, soit à déperrir et à être délaissée par ses utilisateurs.
Et c'est juste cette maintenance qui est difficile.
Selon certaines études académiques et industrielles \cite[]{django_for_startup_founders}, 60 à 80\% du coût associé à n'importe quelle ligne de code correspond à de la maintenance de la ligne initialement écrite.
Les problèmes arriveront lorsqu'une nouvelle fonctionnalité vous sera demandée, lorsqu'un bug sera découvert et devra être corrigé ou lorsqu'une dépendance cessera de fonctionner ou d'être disponible.
Comme une application qui n'évolue pas finira inlassablement par mourir, toute application est destinée:
\begin{itemize}
\item
Soit à être modifiée, corrigée et suivie
\item
Soit à déperrir et à être délaissée par ses utilisateurs.
\end{itemize}
C'est cette maintenance qui est difficile: selon certaines études académiques et industrielles \cite{django_for_startup_founders}, 60 à 80\% du coût associé à n'importe quelle ligne de code correspond à de la maintenance de la ligne initialement écrite.
Ceci est dû à des bogues, à des modifications de fonctionnalités, à des dépendances qui évoluent, qui ne sont plus maintenues ou qui doivent être remplacées.
L'application des principes présentés et agrégés ci-dessous permet surtout de préparer correctement tout ce qui pourra arriver, sans aller jusqu'au « \textbf{You Ain't Gonna Need It} » (ou \textbf{YAGNI\index{YAGNI}}), qui consiste à surcharger tout développement avec des fonctionnalités non demandées, juste « au cas ou ».
Pour paraphraser une partie de l'introduction du livre \emph{Clean Architecture} \cite{clean_architecture}:
L'application des principes présentés et agrégés ci-dessous permet surtout de préparer correctement tout ce qui pourra arriver, sans aller jusqu'à surcharger tout développement par des fonctionnalités non demandées, juste « au cas ou » \footnote{Aussi connu sous l'acronyme \textbf{YAGNI\index{YAGNI}}, ou \textit{\textbf{You Ain't Gonna Need It}}}.
Pour paraphraser une partie de l'introduction du livre \emph{Clean Architecture} :
\begin{quote}
Getting software right is hard: it takes knowledge and skills that most young programmers don't take the time to develop.
\textit{Getting software right is hard: it takes knowledge and skills that most young programmers don't take the time to develop.
It requires a level of discipline and dedication that most programmers never dreamed they'd need.
Mostly, it takes a passion for the craft and the desire to be a professional.
--- Robert C. Martin Clean Architecture
Mostly, it takes a passion for the craft and the desire to be a professional.} \cite{clean_architecture}
\end{quote}
Le développement d'un logiciel nécessite une rigueur d'exécution et des connaissances précises dans des domaines extrêmement variés.
Il nécessite également des intentions, des (bonnes) décisions et énormément d'attention.
Indépendamment de l'architecture que vous aurez choisie, des technologies que vous aurez patiemment évaluées et mises en place, une architecture et une solution peuvent être cassées en un instant, en même temps que tout ce que vous aurez construit, dès que vous en aurez détourné le regard.
Il nécessite également des intentions, des prises de décisions et énormément d'attention.
Indépendamment de l'architecture que vous aurez choisie et des technologies que vous aurez patiemment évaluées, une architecture et une solution peuvent être cassées en un instant, en même temps que tout ce que vous aurez construit, dès que vous en aurez détourné le regard.
Un des objectifs ici est de placer les barrières et les gardes-fous (ou plutôt, les "\textbf{garde-vous}"), afin de péréniser au maximum les acquis, stabiliser les bases de tous les environnements (du développement à la production) qui accueilliront notre application et fiabiliser ainsi chaque étape de communication.
Un des objectifs ici est de placer les barrières et les gardes-fous, afin de péréniser au maximum les acquis, stabiliser les bases de tous les environnements (du développement à la production) qui accueilliront notre application, et ainsi fiabiliser chaque étape de la communication.
Dans cette partie-ci, nous parlerons de \textbf{méthodes de travail}, avec comme objectif d'éviter que l'application ne tourne que sur notre machine et que chaque déploiement ne soit une plaie à gérer.
Chaque mise à jour doit être réalisable de la manière la plus simple possible, et chaque étape doit être rendue la plus automatisée/automatisable possible.
Dans son plus simple élément, une application pourrait être mise à jour simplement en envoyant son code sur un dépôt centralisé: ce déclencheur doit démarrer une chaîne de vérification d'utilisabilité/fonctionnalités/débuggabilité/sécurité, pour immédiatement la mettre à disposition de nouveaux utilisateurs si toute la chaîne indique que tout est OK.
D'autres mécanismes fonctionnent également, mais au plus les actions nécessitent d'actions humaines, voire d'intervenants humains, au plus la probabilité qu'un problème survienne est grande.
Chaque mise à jour doit être réalisable de la manière la plus simple possible, et chaque étape doit être le plus possible automatisée.
Dans une version plus manuelle, cela pourrait se résumer à ces trois étapes (la dernière étant formellement facultative) :
Dans son plus simple élément, la mise à disposition d'une nouvelle version d'une application pourrait se résumer à ces trois étapes:
\begin{enumerate}
\item
Démarrer un script,
\item
Prévoir un rollback si cela plante (et si cela a planté, préparer un post-mortem de l'incident pour qu'il ne se produise plus)
\item
Se préparer une tisane en regardant nos flux RSS (pour peu que cette technologie existe encore\ldots).
\end{enumerate}
\begin{figure}[H]
\centering
\scalebox{1.0}{\includegraphics[max size={\textwidth}{\textheight}]{images/diagrams/deploy-without-hassle.drawio.png}}
\end{figure}
Dans une version plus automatisée, une application pourrait être mise à jour simplement en envoyant son code sur un dépôt centralisé: ce déclencheur a la responsabilité de démarrer une chaîne de vérification d'utilisabilité, de bon fonctionnement et de sécurité, pour immédiatement la mettre à disposition de nouveaux utilisateurs si chaque acteur de cette chaîne indique que tout est OK.
\begin{figure}[H]
\centering
\scalebox{1.0}{\includegraphics[max size={\textwidth}{\textheight}]{images/diagrams/basic-automation.drawio.png}}
\end{figure}
D'autres mécanismes fonctionnent également, mais au plus les actions nécessitent d'actions humaines, voire d'intervenants humains, au plus la probabilité qu'un problème survienne est grande, même dans le cas de processus de routine.
Sans aller jusqu'à demander de développer vos algorithmes sur douze pieds, la programmation reste un art régit par un ensemble de bonnes pratiques, par des règles à respecter et par la nécessité de travailler avec d'autres personnes qui ont souvent une expérience, des compétences ou une approche différente.