Aller au contenu

e

Apprivoisez les composants classe

Composants de Classe

Au cours de ce cours, nous avons uniquement utilisé des composants React définis en tant que fonctions JavaScript. Cela n'était pas possible sans la fonctionnalité de hook qui est arrivée avec la version 16.8 de React. Auparavant, pour définir un composant utilisant un état, on devait le définir en utilisant la syntaxe Class de JavaScript.

Il est bénéfique d'être au moins quelque peu familier avec les composants de classe, car le monde contient beaucoup de vieux code React, qui ne sera probablement jamais entièrement réécrit en utilisant la syntaxe mise à jour.

Familiarisons-nous avec les principales fonctionnalités des composants de classe en produisant une fois de plus une application d'anecdotes très familière. Nous stockons les anecdotes dans le fichier db.json en utilisant json-server. Le contenu du fichier est repris de ici.

La version initiale du composant de classe ressemble à ceci

import React from 'react'

class App extends React.Component {
  constructor(props) {
    super(props)
  }

  render() {
    return (
      <div>
        <h1>anecdote of the day</h1>
      </div>
    )
  }
}

export default App

Le composant possède maintenant un constructeur, dans lequel rien ne se passe pour le moment, et contient la méthode render. Comme on pourrait s'y attendre, render définit comment et ce qui est rendu à l'écran.

Définissons un état pour la liste des anecdotes et l'anecdote actuellement visible. Contrairement à l'utilisation du hook useState, les composants de classe ne contiennent qu'un seul état. Ainsi, si l'état est composé de plusieurs "parties", elles doivent être stockées en tant que propriétés de l'état. L'état est initialisé dans le constructeur:

class App extends React.Component {
  constructor(props) {
    super(props)

    this.state = {      anecdotes: [],      current: 0    }  }

  render() {
    if (this.state.anecdotes.length === 0) {      return <div>no anecdotes...</div>    }
    return (
      <div>
        <h1>anecdote of the day</h1>
        <div>          {this.state.anecdotes[this.state.current].content}        </div>        <button>next</button>      </div>
    )
  }
}

L'état du composant se trouve dans la variable d'instance this.state. L'état est un objet ayant deux propriétés. this.state.anecdotes est la liste des anecdotes et this.state.current est l'index de l'anecdote actuellement affichée.

Dans les composants fonctionnels, l'endroit approprié pour récupérer les données d'un serveur est à l'intérieur d'un hook d'effet, qui est exécuté lorsque le composant se rend ou moins fréquemment si nécessaire, par exemple, uniquement en combinaison avec le premier rendu.

Les méthodes de cycle de vie des composants de classe offrent une fonctionnalité correspondante. L'endroit correct pour déclencher la récupération des données depuis un serveur se trouve à l'intérieur de la méthode de cycle de vie componentDidMount, qui est exécutée une fois juste après le premier rendu du composant:

class App extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      anecdotes: [],
      current: 0
    }
  }

  componentDidMount = () => {    axios.get('http://localhost:3001/anecdotes').then(response => {      this.setState({ anecdotes: response.data })    })  }
  // ...
}

La fonction de rappel de la requête HTTP met à jour l'état du composant en utilisant la méthode setState. La méthode affecte uniquement les clés qui ont été définies dans l'objet passé à la méthode comme argument. La valeur de la clé current reste inchangée.

Appeler la méthode setState déclenche toujours le rerendu du composant de classe, c'est-à-dire l'appel de la méthode render.

Nous allons terminer le composant avec la capacité de changer l'anecdote affichée. Voici le code pour l'ensemble du composant avec l'ajout mis en évidence:

class App extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      anecdotes: [],
      current: 0
    }
  }

  componentDidMount = () => {
    axios.get('http://localhost:3001/anecdotes').then(response => {
      this.setState({ anecdotes: response.data })
    })
  }

  handleClick = () => {    const current = Math.floor(      Math.random() * this.state.anecdotes.length    )    this.setState({ current })  }
  render() {
    if (this.state.anecdotes.length === 0 ) {
      return <div>no anecdotes...</div>
    }

    return (
      <div>
        <h1>anecdote of the day</h1>
        <div>{this.state.anecdotes[this.state.current].content}</div>
        <button onClick={this.handleClick}>next</button>      </div>
    )
  }
}

Pour comparaison, voici la même application en tant que composant fonctionnel:

const App = () => {
  const [anecdotes, setAnecdotes] = useState([])
  const [current, setCurrent] = useState(0)

  useEffect(() =>{
    axios.get('http://localhost:3001/anecdotes').then(response => {
      setAnecdotes(response.data)
    })
  },[])

  const handleClick = () => {
    setCurrent(Math.round(Math.random() * (anecdotes.length - 1)))
  }

  if (anecdotes.length === 0) {
    return <div>no anecdotes...</div>
  }

  return (
    <div>
      <h1>anecdote of the day</h1>
      <div>{anecdotes[current].content}</div>
      <button onClick={handleClick}>next</button>
    </div>
  )
}

Dans le cas de notre exemple, les différences étaient mineures. La plus grande différence entre les composants fonctionnels et les composants de classe est principalement que l'état d'un composant de classe est un objet unique, et que l'état est mis à jour en utilisant la méthode setState, tandis que dans les composants fonctionnels, l'état peut consister en plusieurs variables différentes, chacune ayant sa propre fonction de mise à jour.

Dans certains cas d'utilisation plus avancés, le hook d'effet offre un mécanisme considérablement meilleur pour contrôler les effets secondaires par rapport aux méthodes de cycle de vie des composants de classe.

Un avantage notable de l'utilisation des composants fonctionnels est de ne pas avoir à traiter avec la référence this qui se réfère à elle-même dans la classe Javascript.

À mon avis, et à celui de beaucoup d'autres, les composants de classe offrent peu d'avantages par rapport aux composants fonctionnels améliorés avec des hooks, à l'exception du mécanisme dit de limite d'erreur , qui actuellement (15 février 2021) n'est pas encore utilisé par les composants fonctionnels.

Lors de l'écriture de code frais, il n'y a pas de raison rationnelle d'utiliser des composants de classe si le projet utilise React avec un numéro de version 16.8 ou supérieur. D'autre part, il n'est actuellement pas nécessaire de réécrire tout l'ancien code React comme composants fonctionnels.

Organisation du code dans une application React

Dans la plupart des applications, nous avons suivi le principe selon lequel les composants étaient placés dans le répertoire components, les réducteurs étaient placés dans le répertoire reducers, et le code responsable de la communication avec le serveur était placé dans le répertoire services. Cette manière d'organiser convient très bien à une petite application, mais à mesure que le nombre de composants augmente, des solutions meilleures sont nécessaires. Il n'y a pas une seule manière correcte d'organiser un projet. L'article The 100% correct way to structure a React app (or why there’s no such thing) donne un certain éclairage sur la question.

Frontend et backend dans le même dépôt

Au cours de ce cours, nous avons créé le frontend et le backend dans des dépôts séparés. C'est une approche très typique. Cependant, nous avons effectué le déploiement en copiant le code frontend groupé dans le dépôt backend. Une approche éventuellement meilleure aurait été de déployer le code frontend séparément.

Parfois, il peut y avoir une situation où l'ensemble de l'application doit être mis dans un seul dépôt. Dans ce cas, une approche courante consiste à placer le fichier package.json et webpack.config.js dans le répertoire racine, ainsi qu'à placer le code frontend et backend dans leurs propres répertoires, par exemple client et server.

Changements sur le serveur

S'il y a des changements dans l'état sur le serveur, par exemple, lorsque de nouveaux blogs sont ajoutés par d'autres utilisateurs au service bloglist, le frontend React que nous avons implémenté au cours de ce cours ne remarquera pas ces changements jusqu'à ce que la page soit rechargée. Une situation similaire se présente lorsque le frontend déclenche un calcul long dans le backend. Comment reflétons-nous les résultats du calcul au frontend ?

Une manière est d'exécuter le polling sur le frontend, ce qui signifie des demandes répétées à l'API backend par exemple en utilisant la commande setInterval.

Une manière plus sophistiquée est d'utiliser WebSockets qui permettent d'établir un canal de communication bidirectionnel entre le navigateur et le serveur. Dans ce cas, le navigateur n'a pas besoin d'interroger le backend et doit simplement définir des fonctions de rappel pour les situations où le serveur envoie des données sur la mise à jour de l'état via un WebSocket.

WebSockets est une API fournie par le navigateur, qui n'est pas encore entièrement prise en charge par tous les navigateurs:

caniuse chart showing websockets not usable by all yet

Au lieu d'utiliser directement l'API WebSocket, il est conseillé d'utiliser la bibliothèque Socket.io, qui offre diverses options de fallback au cas où le navigateur n'aurait pas un support complet pour WebSockets.

Dans la partie 8, notre sujet est GraphQL, qui fournit un mécanisme agréable pour notifier les clients lorsqu'il y a des changements dans les données du backend.

Virtual DOM

Le concept de Virtual DOM est souvent évoqué lorsqu'on parle de React. De quoi s'agit-il ? Comme mentionné dans la partie 0, les navigateurs fournissent une API DOM grâce à laquelle le JavaScript exécuté par le navigateur peut modifier les éléments définissant l'apparence de la page.

Lorsqu'un développeur utilise React, il manipule rarement ou jamais directement le DOM. La fonction définissant le composant React retourne un ensemble d'éléments React. Bien que certains des éléments ressemblent à des éléments HTML normaux

const element = <h1>Hello, world</h1>

ils sont également, au fond, des éléments React basés sur JavaScript.

Les éléments React définissant l'apparence des composants de l'application composent le DOM Virtuel, qui est stocké dans la mémoire système pendant l'exécution.

Avec l'aide de la bibliothèque ReactDOM, le DOM virtuel défini par les composants est rendu à un vrai DOM qui peut être affiché par le navigateur en utilisant l'API DOM:

ReactDOM.createRoot(document.getElementById('root')).render(<App />)

Lorsque l'état de l'application change, un nouveau DOM virtuel est défini par les composants. React a la version précédente du DOM virtuel en mémoire et, au lieu de rendre directement le nouveau DOM virtuel en utilisant l'API DOM, React calcule la manière optimale de mettre à jour le DOM (supprimer, ajouter ou modifier des éléments dans le DOM) de manière à ce que le DOM reflète le nouveau DOM virtuel.

Sur le rôle de React dans les applications

Dans le matériel, nous n'avons peut-être pas suffisamment souligné le fait que React est principalement une bibliothèque pour gérer la création de vues pour une application. Si nous regardons le schéma traditionnel Modèle Vue Contrôleur (MVC) , alors le domaine de React serait Vue. React a une aire d'application plus restreinte que, par exemple, Angular, qui est un cadre MVC frontal complet. Par conséquent, React n'est pas appelé un cadre (framework), mais une bibliothèque (library).

Dans les petites applications, les données manipulées par l'application sont stockées dans l'état des composants React, donc dans ce scénario, l'état des composants peut être considéré comme les modèles d'une architecture MVC.

Cependant, l'architecture MVC n'est généralement pas mentionnée lorsqu'on parle d'applications React. De plus, si nous utilisons Redux, alors les applications suivent l'architecture Flux et le rôle de React est encore plus centré sur la création des vues. La logique métier de l'application est gérée en utilisant l'état et les créateurs d'actions Redux. Si nous utilisons Redux Thunk connu de la partie 6, alors la logique métier peut être presque complètement séparée du code React.

Étant donné que React et Flux ont été créés chez Facebook, on pourrait dire que l'utilisation de React uniquement comme une bibliothèque UI est le cas d'utilisation prévu. Suivre l'architecture Flux ajoute une certaine surcharge à l'application et si nous parlons d'une petite application ou d'un prototype, il pourrait être judicieux d'utiliser React de manière "incorrecte", puisque la sur-ingénierie donne rarement un résultat optimal.

Le dernier chapitre de la partie 6 couvre les tendances plus récentes de gestion d'état dans React. Les fonctions hook useReducer et useContext de React fournissent une sorte de version allégée de Redux. React Query, d'autre part, est une bibliothèque qui résout de nombreux problèmes associés à la gestion de l'état sur le serveur, éliminant le besoin pour une application React de stocker directement les données récupérées du serveur dans l'état frontal.

Sécurité des applications React/node

Jusqu'à présent, au cours de ce cours, nous n'avons pas beaucoup abordé la sécurité de l'information. Nous n'avons pas non plus beaucoup de temps pour cela maintenant, mais heureusement, l'Université d'Helsinki propose un cours MOOC Securing Software pour ce sujet important.

Cependant, nous allons jeter un oeil à quelques spécificités de ce cours.

Le Open Web Application Security Project, connu sous le nom de OWASP, publie une liste annuelle des risques de sécurité les plus courants dans les applications Web. La liste la plus récente peut être trouvée ici. Les mêmes risques se retrouvent d'une année à l'autre.

En haut de la liste, nous trouvons l'injection, ce qui signifie que, par exemple, le texte envoyé à l'aide d'un formulaire dans une application est interprété de manière complètement différente de ce que le développeur de logiciels avait prévu. Le type d'injection le plus célèbre est probablement l'injection SQL.

Par exemple, imaginez que la requête SQL suivante soit exécutée dans une application vulnérable:

let query = "SELECT * FROM Users WHERE name = '" + userName + "';"

Maintenant, supposons qu'un utilisateur malveillant, Arto Hellas, définisse son nom comme


Arto Hell-as'; DROP TABLE Users; --

Les injections SQL sont évitées en utilisant des requêtes paramétrées. Avec elles, les entrées des utilisateurs ne sont pas mélangées avec la requête SQL, mais la base de données elle-même insère les valeurs d'entrée à des emplacements réservés dans la requête (généralement ?).

execute("SELECT * FROM Users WHERE name = ?", [userName])

Les attaques par injection sont également possibles dans les bases de données NoSQL. Cependant, mongoose les empêche en sanitisant les requêtes. Plus d'informations sur le sujet peuvent être trouvées par exemple ici.

Le Cross-site scripting (XSS) est une attaque où il est possible d'injecter du code JavaScript malveillant dans une application web légitime. Le code malveillant serait alors exécuté dans le navigateur de la victime. Si nous essayons d'injecter le suivant dans par exemple l'application de notes:

<script>
  alert('Evil XSS attack')
</script>

le code n'est pas exécuté, mais est uniquement rendu comme 'texte' sur la page:

browser showing notes with XSS attempt

car React s'occupe de la sanitation des données dans les variables. Certaines versions de React ont été vulnérables aux attaques XSS. Les failles de sécurité ont bien sûr été corrigées, mais il n'y a aucune garantie qu'il n'y en ait pas d'autres.

Il faut rester vigilant lors de l'utilisation des bibliothèques; si des mises à jour de sécurité pour ces bibliothèques sont disponibles, il est conseillé de mettre à jour ces bibliothèques dans ses applications. Les mises à jour de sécurité pour Express se trouvent dans la documentation de la bibliothèque et celles pour Node se trouvent dans ce blog.

Vous pouvez vérifier à quel point vos dépendances sont à jour en utilisant la commande

npm outdated --depth 0

Le projet vieux d'un an utilisé dans la partie 9 de ce cours a déjà un certain nombre de dépendances obsolètes:

npm outdated output of patientor

Les dépendances peuvent être mises à jour en actualisant le fichier package.json. La meilleure façon de faire cela est d'utiliser un outil appelé npm-check-updates. Il peut être installé globalement en exécutant la commande

npm install -g npm-check-updates

En utilisant cet outil, la vérification de l'actualité des dépendances se fait de la manière suivante:

$ npm-check-updates
Checking ...\ultimate-hooks\package.json
[====================] 9/9 100%

 @testing-library/react       ^13.0.0  →  ^13.1.1
 @testing-library/user-event  ^14.0.4  →  ^14.1.1
 react-scripts                  5.0.0  →    5.0.1

Run ncu -u to upgrade package.json

Le fichier package.json est mis à jour en exécutant la commande ncu -u.

$ ncu -u
Upgrading ...\ultimate-hooks\package.json
[====================] 9/9 100%

 @testing-library/react       ^13.0.0  →  ^13.1.1
 @testing-library/user-event  ^14.0.4  →  ^14.1.1
 react-scripts                  5.0.0  →    5.0.1

Run npm install to install new versions.

Il est ensuite temps de mettre à jour les dépendances en exécutant la commande npm install. Cependant, les anciennes versions des dépendances ne sont pas nécessairement un risque de sécurité.

La commande npm audit peut être utilisée pour vérifier la sécurité des dépendances. Elle compare les numéros de version des dépendances de votre application à une liste de numéros de version de dépendances contenant des menaces de sécurité connues dans une base de données d'erreurs centralisée.

Exécuter npm audit sur le même projet affiche une longue liste de plaintes et de corrections suggérées. Voici une partie du rapport:

$ patientor npm audit

... many lines removed ...

url-parse  <1.5.2
Severity: moderate
Open redirect in url-parse - https://github.com/advisories/GHSA-hh27-ffr2-f2jc
fix available via `npm audit fix`
node_modules/url-parse

ws  6.0.0 - 6.2.1 || 7.0.0 - 7.4.5
Severity: moderate
ReDoS in Sec-Websocket-Protocol header - https://github.com/advisories/GHSA-6fc8-4gx4-v693
ReDoS in Sec-Websocket-Protocol header - https://github.com/advisories/GHSA-6fc8-4gx4-v693
fix available via `npm audit fix`
node_modules/webpack-dev-server/node_modules/ws
node_modules/ws

120 vulnerabilities (102 moderate, 16 high, 2 critical)

To address issues that do not require attention, run:
  npm audit fix

To address all issues (including breaking changes), run:
  npm audit fix --force

Après seulement un an, le code est plein de petites menaces de sécurité. Heureusement, il n'y a que 2 menaces critiques. Exécutons npm audit fix comme le suggère le rapport:

$ npm audit fix

+ mongoose@5.9.1
added 19 packages from 8 contributors, removed 8 packages and updated 15 packages in 7.325s
fixed 354 of 416 vulnerabilities in 20047 scanned packages
  1 package update for 62 vulns involved breaking changes
  (use `npm audit fix --force` to install breaking changes; or refer to `npm audit` for steps to fix these manually)

62 menaces restent parce que, par défaut, audit fix ne met pas à jour les dépendances si leur numéro de version majeure a augmenté. Mettre à jour ces dépendances pourrait entraîner l'effondrement de toute l'application.

La source du bug critique est la bibliothèque immer

immer  <9.0.6
Severity: critical
Prototype Pollution in immer - https://github.com/advisories/GHSA-33f9-j839-rf8h
fix available via `npm audit fix --force`
Will install react-scripts@5.0.0, which is a breaking change

Exécuter npm audit fix --force mettrait à jour la version de la bibliothèque mais mettrait également à jour la bibliothèque react-scripts, ce qui pourrait potentiellement détruire l'environnement de développement. Nous laisserons donc les mises à jour des bibliothèques pour plus tard...

L'une des menaces mentionnées dans la liste de l'OWASP est Broken Authentication et le Broken Access Control lié. L'authentification basée sur les jetons que nous avons utilisée est assez robuste si l'application est utilisée sur le protocole HTTPS qui crypte le trafic. Lors de la mise en oeuvre du contrôle d'accès, il faut par exemple se rappeler de ne pas seulement vérifier l'identité d'un utilisateur dans le navigateur, mais aussi sur le serveur. Une mauvaise sécurité consisterait à empêcher certaines actions d'être prises uniquement en cachant les options d'exécution dans le code du navigateur.

Sur MDN de Mozilla, il existe un très bon guide de sécurité des sites web, qui aborde ce sujet très important:

capture d'écran de la sécurité des sites web sur MDN

La documentation d'Express comprend une section sur la sécurité: Pratiques recommandées en production: Sécurité, qui mérite d'être lue. Il est également recommandé d'ajouter une bibliothèque appelée Helmet au backend. Elle comprend un ensemble de middleware qui élimine certaines vulnérabilités de sécurité dans les applications Express.

L'utilisation du plugin de sécurité ESlint est également à prévoir.

Tendances actuelles

Enfin, examinons un peu la technologie de demain (ou, en réalité, déjà d'aujourd'hui) et les directions dans lesquelles le développement Web se dirige.

Versions typées de JavaScript

Parfois, le typage dynamique des variables JavaScript crée des bugs ennuyeux. Dans la partie 5, nous avons brièvement parlé des PropTypes: un mécanisme qui permet d'imposer le contrôle de type pour les props passées aux composants React.

Dernièrement, il y a eu un intérêt notable pour le contrôle de type statique. Actuellement, la version typée de Javascript la plus populaire est TypeScript qui a été développée par Microsoft. TypeScript est couvert dans la partie 9.

Rendu côté serveur, applications isomorphes et code universel

Le navigateur n'est pas le seul domaine où les composants définis en utilisant React peuvent être rendus. Le rendu peut également être effectué sur le serveur. Ce type d'approche est de plus en plus utilisé, de sorte que, lors de l'accès à l'application pour la première fois, le serveur fournit une page pré-rendue faite avec React. À partir de là, le fonctionnement de l'application continue comme d'habitude, ce qui signifie que le navigateur exécute React, qui manipule le DOM affiché par le navigateur. Le rendu effectué sur le serveur porte le nom de: rendu côté serveur.

Une motivation pour le rendu côté serveur est l'optimisation pour les moteurs de recherche (SEO). Traditionnellement, les moteurs de recherche ont été très mauvais pour reconnaître le contenu rendu par JavaScript. Cependant, la tendance pourrait être en train de changer, par exemple, jetez un oeil à ceci et cela.

Bien sûr, le rendu côté serveur n'est pas spécifique à React ou même à JavaScript. Utiliser le même langage de programmation à travers la pile en théorie simplifie l'exécution du concept parce que le même code peut être exécuté à la fois sur le front-end et le back-end.

Avec le rendu côté serveur, il a été question des soi-disant applications isomorphes et du code universel, bien qu'il y ait eu un certain débat sur leurs définitions. Selon certaines définitions, une application web isomorphe effectue le rendu à la fois sur le front-end et le back-end. D'un autre côté, le code universel est un code qui peut être exécuté dans la plupart des environnements, ce qui signifie à la fois le front-end et le back-end.

React et Node offrent une option désirable pour implémenter une application isomorphe en tant que code universel.

Écrire directement du code universel en utilisant React est actuellement encore assez laborieux. Dernièrement, une bibliothèque appelée Next.js, qui est mise en oeuvre au-dessus de React, a attiré beaucoup d'attention et est une bonne option pour faire des applications universelles.

Applications web progressives

Dernièrement, les gens ont commencé à utiliser le terme application web progressive (PWA) lancé par Google.

En bref, nous parlons d'applications web fonctionnant aussi bien que possible sur chaque plateforme et tirant parti des meilleurs aspects de ces plateformes. L'écran plus petit des appareils mobiles ne doit pas entraver l'utilisabilité de l'application. Les PWA devraient également fonctionner parfaitement en mode hors ligne ou avec une connexion Internet lente. Sur les appareils mobiles, ils doivent être installables comme n'importe quelle autre application. Tout le trafic réseau dans une PWA devrait être chiffré.

Architecture microservices

Pendant ce cours, nous avons juste effleuré la surface du côté serveur des choses. Dans nos applications, nous avions un backend monolithique, signifiant une application formant un tout et fonctionnant sur un seul serveur, servant seulement quelques points d'API.

À mesure que l'application grandit, l'approche backend monolithique commence à poser problème tant en termes de performance que de maintenabilité.

Une architecture microservices est une façon de composer le backend d'une application à partir de nombreux services séparés et indépendants, qui communiquent entre eux sur le réseau. Le but d'un microservice individuel est de s'occuper d'un ensemble fonctionnel logique particulier. Dans une architecture microservices pure, les services n'utilisent pas une base de données partagée.

Par exemple, l'application bloglist pourrait consister en deux services : un gérant l'utilisateur et un autre prenant en charge les blogs. La responsabilité du service utilisateur serait l'inscription et l'authentification des utilisateurs, tandis que le service blog s'occuperait des opérations liées aux blogs.

L'image ci-dessous visualise la différence entre la structure d'une application basée sur une architecture microservices et celle basée sur une structure monolithique plus traditionnelle:

diagramme comparant microservices et approche traditionnelle

Le rôle du frontend (encadré sur l'image) ne diffère pas beaucoup entre les deux modèles. Il y a souvent ce qu'on appelle une passerelle API entre les microservices et le frontend, qui fournit une illusion d'une API "tout sur le même serveur" plus traditionnelle. Netflix, entre autres, utilise ce type d'approche.

Les architectures microservices sont apparues et se sont développées pour les besoins des applications à grande échelle sur Internet. La tendance a été établie par Amazon bien avant l'apparition du terme microservice. Le point de départ crucial a été un courriel envoyé à tous les employés en 2002 par le PDG d'Amazon, Jeff Bezos:

Toutes les équipes exposeront désormais leurs données et fonctionnalités à travers des interfaces de service.

Les équipes doivent communiquer entre elles à travers ces interfaces.

Il n'y aura aucune autre forme de communication inter-processus autorisée : pas de liaison directe, pas de lectures directes de la base de données d'une autre équipe, pas de modèle de mémoire partagée, absolument aucune porte dérobée. La seule communication autorisée est via des appels d'interface de service sur le réseau.

Peu importe la technologie que vous utilisez.

Toutes les interfaces de service, sans exception, doivent être conçues dès le départ pour être externalisables. C'est-à-dire que l'équipe doit planifier et concevoir pour être en mesure d'exposer l'interface aux développeurs du monde extérieur.

Pas d'exceptions.

Quiconque ne fait pas cela sera licencié. Merci; passez une bonne journée!

Aujourd'hui, l'un des plus grands précurseurs de l'utilisation des microservices est Netflix.

L'utilisation des microservices a été progressivement perçue comme une sorte de balle magique d'aujourd'hui, qui est proposée comme solution à presque tous les types de problèmes. Cependant, il y a plusieurs défis à appliquer une architecture microservices, et cela pourrait être sensé de commencer d'abord par un monolithe en faisant initialement un backend tout-en-un traditionnel. Ou peut-être pas. Il y a un tas d'opinions différentes sur le sujet. Les deux liens mènent au site de Martin Fowler; comme nous pouvons le voir, même les sages ne sont pas tout à fait sûrs de quelle voie est la plus juste.

Malheureusement, nous ne pouvons pas approfondir davantage ce sujet important pendant ce cours. Même un coup d'oeil superficiel sur le sujet nécessiterait au moins 5 semaines supplémentaires.

Serverless

Après le lancement du service lambda d'Amazon fin 2014, une nouvelle tendance a commencé à émerger dans le développement d'applications web: serverless.

La particularité de lambda, et aujourd'hui aussi des Cloud functions de Google ainsi que de fonctionnalités similaires dans Azure, est qu'elle permet l'exécution de fonctions individuelles dans le cloud. Auparavant, la plus petite unité exécutable dans le cloud était un seul processus, par exemple, un environnement d'exécution exécutant un backend Node.

Par exemple, en utilisant la passerelle API d'Amazon, il est possible de créer des applications serverless où les requêtes à l'API HTTP définie obtiennent des réponses directement des fonctions cloud. Habituellement, les fonctions fonctionnent déjà avec des données stockées dans les bases de données du service cloud.

Serverless ne signifie pas qu'il n'y a pas de serveur dans les applications, mais comment le serveur est défini. Les développeurs de logiciels peuvent déplacer leurs efforts de programmation vers un niveau d'abstraction plus élevé car il n'est plus nécessaire de définir programmatiquement le routage des requêtes HTTP, les relations de base de données, etc., puisque l'infrastructure cloud fournit tout cela. Les fonctions cloud se prêtent également à la création d'un système bien évolutif, par exemple, Lambda d'Amazon peut exécuter une énorme quantité de fonctions cloud par seconde. Tout cela se produit automatiquement grâce à l'infrastructure et il n'est pas nécessaire d'initier de nouveaux serveurs, etc.

Bibliothèques utiles et liens intéressants

La communauté des développeurs JavaScript a produit une grande variété de bibliothèques utiles. Si vous développez quelque chose de plus substantiel, il vaut la peine de vérifier si des solutions existantes sont déjà disponibles. Ci-dessous sont listées certaines bibliothèques recommandées par des parties dignes de confiance.

Si votre application doit gérer des données complexes, lodash, que nous avons recommandé dans la partie 4, est une bonne bibliothèque à utiliser. Si vous préférez le style de programmation fonctionnel, vous pourriez envisager d'utiliser ramda.

Si vous gérez des dates et heures, date-fns offre de bons outils pour cela. Si vous avez des formulaires complexes dans vos applications, regardez si React Hook Form pourrait être un bon choix. Si votre application affiche des graphiques, il y a plusieurs options à choisir. recharts et highcharts sont bien recommandés.

Immer fournit des implémentations immuables de certaines structures de données. La bibliothèque pourrait être utile lors de l'utilisation de Redux, car comme nous nous en souvenons dans la partie 6, les réducteurs doivent être des fonctions pures, c'est-à-dire qu'ils ne doivent pas modifier l'état du store mais doivent le remplacer par un nouveau lorsqu'un changement se produit.

Redux-saga fournit une autre manière de faire des actions asynchrones pour Redux Thunk connu de la partie 6. Certains embrassent le battage médiatique et l'apprécient. Je ne le fais pas.

Pour les applications à page unique, la collecte de données analytiques sur l'interaction entre les utilisateurs et la page est plus difficile que pour les applications web traditionnelles où la page entière est chargée. La bibliothèque React Google Analytics 4 offre une solution.

Vous pouvez profiter de vos connaissances en React lors du développement d'applications mobiles en utilisant la bibliothèque extrêmement populaire React Native de Facebook, qui est le sujet de la partie 10 du cours.

En ce qui concerne les outils utilisés pour la gestion et le bundling des projets JavaScript, la communauté a été très versatile. Les meilleures pratiques ont changé rapidement (les années sont approximatives, personne ne se souvient si loin dans le passé):

Les hipsters semblent avoir perdu leur intérêt pour le développement d'outils après que webpack a commencé à dominer les marchés. Il y a quelques années, Parcel a commencé à se faire connaître en se commercialisant comme simple (ce que Webpack n'est pas) et plus rapide que Webpack. Cependant, après un début prometteur, Parcel n'a pas rassemblé de vapeur, et il commence à ressembler à ce qu'il ne sera pas la fin de Webpack. Récemment, esbuild a été en hausse relativement élevée et défie sérieusement Webpack.

Le site https://reactpatterns.com/ fournit une liste concise des meilleures pratiques pour React, dont certaines sont déjà familières depuis ce cours. Une autre liste similaire est react bits.

Reactiflux est une grande communauté de chat de développeurs React sur Discord. Cela pourrait être un endroit possible pour obtenir du soutien après la fin du cours. Par exemple, de nombreuses bibliothèques ont leurs propres canaux.

Si vous connaissez des liens ou des bibliothèques recommandables, faites un pull request!