Aller au contenu principal Aller au pied de page

Architecture d'une application de notifications

«  Comment contacter une personne en fonction de l'urgence, avec le meilleur média  »

Retour

Un peu de contexte

Nous avons été contacté pour réaliser une application de notifications. Le principe peut se résumer ainsi : sachant que n'importe quel acteur (humain ou application) peut notifier n'importe quel autre acteur d'une entreprise, choisir le meilleur média pour délivrer cette notification.

Les notifications, cela peut être n'importe quoi :

  • Un simple message laissé à l'attention d'une personne, sans action nécessaire.
  • Un mail pour confirmer une action dans le cadre d'un process d'entreprise, avec deux boutons : Valider et Refuser.
  • Prévenir le service informatique de l'interruption de service d'une application critique.
  • ...

En fonction de différents critères, ces différentes notifications peuvent se retrouver envoyées différemment. Par exemple, un résumé des messages en fin de semaine par mail ; un mail avec le contenu de la notification ; un SMS ; un appel automatique.
Ces critères sont définis par plusieurs personnes et leur application est multifactorielle : l'entreprise peut définir des règles générales concernant les expéditeurs ou les destinaires, des plages horaires ou journalières, et l'expéditeur peut également définir une priorité.

Nous avons été sollicités pour deux étapes de la réalisation : tout d'abord, un rapport d'analyse sur l'organisation du code et les choix techniques ; puis, la réalisation de la première version de cette application, fonctionnant uniquement en ligne et sans interface graphique.

Dans ce cadre de ce projet, nous avions à notre disposition :

  • Un cahier des charges présentant l'application
  • Un Swagger (fichier OpenAPI) décrivant les appels à cette application
  • Une collection de tests (Bruno) vérifiant le bon fonctionnement de l'application à venir

Comme cette demande est récente, nous amenderons cette étude de cas si les versions ultérieures se réalisent !

Analyse architecturale

L'analyse architecturale a consisté à découper la totalité des actions réalisées par l'application à venir sous la forme d'un diagramme. Voici, à titre d'exemple, quelques questions ayant accompagné la réalisation de l'architecture :

  • Comment s'assure-t-on de l'expéditeur : est-il celui qu'il prétend être, a-t-il le droit de contacter le destinataire et d'utiliser cette application ?
  • Comment récupère-t-on les informations de contact du destinataire : en fonction de la priorité définie, quels canaux sont valides ? Si un canal de communication est censé être disponible mais ne l'est pas, que doit-on faire ?
  • Comment s'assure-t-on de la structure de la notification ? Les SMS n'ont pas le même format qu'un mail ou qu'un appel ; il faudra structurer la donnée correctement.
  • Comment gérer les pièces jointes dans le cas d'un mail, y a-t-il des contraintes à respecter ?
  • Quelles actions sont à prévoir pour la résilience de l'application ? Dans le cas où un mail doit être envoyé instantanément, comment s'assurer que ce soit le cas même avec défaillance du système envoyant les mails ?
  • Pour rendre l'application la plus pérenne possible, quels standards utiliser au sein du code pour faciliter l'arrivée de nouvelles personnes ou agents IA dans le développement ?

En échangeant avec le client et en réalisant des diagrammes sur feuille, nous avons réalisé cette analyse, ainsi qu'une estimation des délais pour la réalisation de la première version, toutes deux validées par notre donneur d'ordres.

Voici les éléments saillants de l'architecture :

  • Le système d'authentification sera réalisé en frontal, devant l'application : de fait, il n'est pas nécessaire de valider les autorisations des expéditeurs dans le code, celle-ci sera réalisée par un outil en amont et l'application configurée pour n'accepter que des requêtes venant de ce système d'authentification.
  • Venant ensuite, une adresse /notify prenant différents paramètres, structurées en données JSON. Le choix a été fait de ne pas respecter REST (qui aurait donné l'adresse /notifications) pour se laisser davantage de latitude sur ce système qui est foncièrement orienté actions et non ressources
  • Les données reçues sont ensuite formattées dans un objet implémentant l'interface INotification créé pour l'occasion, structurant ainsi les données obligatoires et les actions disponibles. Différentes classes de notification peuvent être créées pour profiter au mieux des différents médias : la classe MailNotification dispose d'un champ "objet" et d'un champ "pièces jointes", que ne possèdera pas la classe ShortMessageServiceNotification par exemple.
  • Une centralisation des fournisseurs externes envoyant la notification, par une interface simple de résolution du canal de communication. En termes plus simples, un seul appel choisissant le bon service en fonction de la notification
  • Une centralisation équivalente pour récupérer les informations de contact du destinataire : cette récupération est dépendante du fournisseur. En effet, il ne faudrait pas récupérer un numéro de téléphone au moment d'envoyer un mail !
  • Un respect complet de la spécification HTTP avec les différents retours de l'application, via les codes de statuts. A ce titre, certains ajustements ont été fait sur la spécification originale fournie par le client, avec son accord.

Si nous ne pouvons pas vous produire le document d'analyse par confidentialité pour nos clients, nous pouvons vous lister les différentes sections de notre rapport d'analyse de dix pages :

  • Contexte
  • Proposition d'architecture et schéma
  • Déroulement d'une requête et schéma
  • Détail des composants
  • Exemple de requête HTTP
  • Environnement d'exécution
  • Risques identifiés et préconisations
  • Planning prévisionnel de réalisation et chiffrage

Retour d'expérience et version initiale

Comme nous avions la charge de réaliser la première version de cette application, c'était l'occasion de valider nos choix directement !

Nous sommes fiers de confirmer que tout s'est passé comme prévu. Les seuls points qui ont échappé à notre vigilance : deux interfaces oubliés pour créer un code parfaitement structuré.

La plupart des éléments ayant changé nos estimations de temps ont été liés au fonctionnement dual : à la fois en direct et dans un conteneur Docker, avec HTTP (développement Docker) ou HTTPS (développement local ou production).

Au vu de l'architecture, il était plus simple de fonctionner sur un mode TDD (Test Driven Development) : nous avons donc réalisé la structure minimale, puis les tests fonctionnels complétant les tests e2e (end to end, de bout-en-bout) fournis au moment de la spécification. Enfin, nous avons réalisé le code.

Notre rendu s'est déroulé dans les temps et contenait :

  • Une solution Visual Studio
  • Un projet pour l'application, avec :
    • La documentation via Swagger, générée par le code et conforme à la spécification
    • La documentation technique au format Markdown pour décrire le projet et expliquer comment l'exécuter
    • Le code de la première version, commenté selon les bonnes pratiques C#
    • Les fichiers liés à l'environnement de développement : certificat HTTPS, Dockerfile, ...
  • Un projet pour les tests, avec :
    • La documentation technique au format Markdown pour lancer les tests
    • Les tests fonctionnels utilisant le client HTTP, commentés selon les bonnes pratiques C#

L'intégration chez le client a déclenché une erreur de configuration à cause d'une faute de frappe dans notre documentation, mais nous avons rapidement pu corriger et assister par visio pour résoudre le problème.

L'implémentation réelle chez le client semble s'être bien passée : tous les retours étaient positifs, et nous avons eu la confirmation que cette première version était intégrée au système d'information.
C'est toujours difficile d'avoir l'ensemble des retours en détail et c'est bien normal : quand nous réalisons une application, nous ne nous attendons pas qu'elle soit mise en ligne tout de suite, car la temporalité des projets est différente pour chaque entreprise.

En tous cas, c'était un plaisir de travailler sur ce projet et nous espérons en avoir d'autres : réfléchir à l'architecture d'une application est tout aussi intéressant que la développer dans son entièreté.